@Specializes in Spring

CDI has a Specialization feature, and I'm looking for it in the Spring world.

Details In CDI, the @Specializes annotation allows @Specializes to change the behavior of a bean only by overriding it. It is completely transparent to users of this bean, for example. if we had

 public class OneBean { public String whoAmI() { return "OneBean"; } } @Specializes public class AnotherBean extends OneBean { @Override public String whoAmI() { return "AnotherBean"; } } 

we could

 public class SomewhereElse { @Inject OneBean oneBean; // we know nothing of AnotherBean here! public void guessWhosThere() { return oneBean.whoAmI(); // yet it returns "AnotherBean" } } 

It becomes really useful once OneBean actually used with and without AnotherBean . For example, if OneBean is in one.jar and AnotherBean is in another.jar , we can only change the behavior of the bean by reconfiguring the class path.

Question. Is there something like specialization in Spring?

I could only find the @Primary annotation, which, however, has different semantics: @Primary does not replace one bean, but only marks one of several alternatives as primary. Especially, as I understand it, I could not build a hierarchy of deep inheritance, as far as possible, using @Specializes .

+7
spring subclass cdi specialization
source share
4 answers

Short answer In Spring 4, this is not possible. Period. However, in 2016, with the help of Spring, an outdated dependency injection model is possible.

+2
source share

It seems like there is no such annotation in spring, but you can get it via @Qualifier.

Beans:

 @Resource("oneBean") public class OneBean { public String whoAmI() { return "OneBean"; } } @Resource("anotherBean") public class AnotherBean extends OneBean { @Override public String whoAmI() { return "AnotherBean"; } } 

SomewhereElse:

 public class SomewhereElse { @Autowired @Qualifier("anotherBean") OneBean oneBean; public void guessWhosThere() { return oneBean.whoAmI(); // returns "AnotherBean" } } 

Ed.

You can also create your own annotation and use it in BeanPostProcessor , see spring docs here

OR it is even better to use CustomAutowireConfigurer , see here

+1
source share

Assuming that:

 public interface BeanInterface { String whoAmI(); } @Named public class OneBean implements BeanInterface { @Override public String whoAmI() { return "OneBean"; } } @Named @Primary public class AnotherBean implements BeanInterface { @Inject OneBean oneBean; @Override public String whoAmI() { String oneBeanId = oneBean.whoAmI(); return "AnotherBean calling: " + oneBeanId; } } 

instead of expanding OneBean we could decorate it with some additional behavior. The disadvantage of this solution is that each BeanInterface method must be implemented in AnotherBean and delegated to its OneBean field.

0
source share

You can use @Qualifier for this.

For example:

Bean Class:

 @Component("loginMB") @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS) public class LoginMB extends AdminSession implements Serializable { 

And the injection point:

 @Component public class AdminFilter implements Filter { private static final String FACES_RESOURCES = "javax.faces.resource"; private static final Logger log = Logger.getLogger(AdminFilter.class.getName()); private boolean disableFilter; private String loginPage; private String errorPage; private String indexPage; @Autowired @Qualifier(value = "loginMB") AdminSession adminSession; 
0
source share

All Articles