Skip to content

Instantly share code, notes, and snippets.

@moelholm
Last active October 13, 2016 16:31
Show Gist options
  • Save moelholm/4317e93f18b02e9582afefc152debb44 to your computer and use it in GitHub Desktop.
Save moelholm/4317e93f18b02e9582afefc152debb44 to your computer and use it in GitHub Desktop.
Spring Framework needs @Nonbinding like support
This example shows why we could use @Nonbinding like support in Qualifier annotations (as known from CDI)
package com.moelholm;
import org.springframework.beans.factory.annotation.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface Lowercase {
String value() default "";
}
package com.moelholm;
import org.springframework.beans.factory.annotation.Qualifier;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface Uppercase {
String value() default "";
}
package com.moelholm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class GreeterService {
@Autowired
@Uppercase("hElLo WoRlD")
private String upper;
@Autowired
@Lowercase("hElLo WoRlD")
private String lower;
public String sayHello(String caller) {
return String.format("%s (%s), %s", upper, lower, caller);
}
}
package com.moelholm;
import static org.springframework.core.annotation.AnnotationUtils.findAnnotation;
import org.springframework.beans.factory.InjectionPoint;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class MyBeanConfig {
@Bean
@Uppercase("hElLo WoRlD")// Spring needs @Nonbinding so that we can remove this 'value'
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public String uppercase(InjectionPoint ip) {
Uppercase annotation = findAnnotation(ip.getAnnotatedElement(), Uppercase.class);
return annotation.value().toUpperCase();
}
@Bean
@Lowercase("hElLo WoRlD")// Spring needs @Nonbinding so that we can remove this 'value'
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public String lowercase(InjectionPoint ip) {
Lowercase annotation = findAnnotation(ip.getAnnotatedElement(), Lowercase.class);
return annotation.value().toLowerCase();
}
}
@jhoeller
Copy link

Point taken, this looks like a worthwhile scenario, even I haven't encountered this in practice yet. I wouldn't bake the non-binding part into the annotation type though; I'd intuitively rather specify something like @Uppercase("*") to express such a flexible match on the @Bean method. Along such lines, a specified value wouldn't get silently ignored, making the bean declaration's intention more obvious.

In any case, if you'd like to see a first-class way of modelling such a scenario in Spring, please raise it on our JIRA.

@struberg
Copy link

struberg commented Oct 10, 2016

- import org.springframework.beans.factory.annotation.Qualifier;
+ import javax.inject.Qualifier;

@moelholm
Copy link
Author

Hi Juergen,

Thank you for taking a look at this.

To be honest I think the "need" is new - comes with the InjectionPoint introduction. That is also why I think it hasn't been raised before.

I do still think that non binding support makes sense for non string attribute values as well. Although probably not as useful for practical purposes.

Just my two cents :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment