Say that I have class Controller with property strategy of type IStrategy. In Spring, I can create different instances of Controller and inject different strategy implementations by defining beans in xml configuration file as shown below:
<bean id="strategyAController" class="com.test.Controller">
<property name="strategy" ref="strategyAImpl">
</bean>
<bean id="strategyBController" class="com.test.Controller">
<property name="strategy" ref="strategyBImpl">
</bean>
<bean id="strategycController" class="com.test.Controller">
<property name="strategy" ref="strategycImpl">
</bean>
I can then reference these beans using #Autowired and #Qualifier("strategyAController"), etc. What is the equivalent way of doing this in Java EE 6
Funny you should ask! Gavin King, who designed Java EE 6 CDI, got into a nasty fight with someone on exactly the same problem.
http://www.tsolak.com/?p=59
The Spring code, of course, looks awfully like Java. We can do that in java - create some variables, set some properties, no biggie. I am curious, in your perticular application, what's the drawback of doing it in plain Java? What's the specific benefit you get from Spring for these beans?
In CDI you can use Qualifer to identify the different instances and producer methods to provide that instances.
public class ControllerFactory {
#Produces
#StrategyA
public Controller createControllerA {
return new Controller(configA);
}
#Produces
#StrategyB
public Controller createControllerB {
return new Controller(configB);
}
}
#StrategyB
#Inject
Controller howToAccessIt;
If you do not like to create a new StrategyA/B/C Annotation for each strategy, you could use one Annotation with an Field (for example an Enum) that identify the strategy. So that you can write: #Strategy(StratType.A).
Then you can use the InjectionPoint in your producer method, so that you can create the instance depending on the annotation in a generic way, instead of writing a new producer method for each Strategy:
#Produces
//must add a Annotation to clarify that this producer produces for all Strategies!
public Controller createController(InjetionPoint ip) {
Annotated annotated = ip.getAnnotated();
if (annotated.isAnnotationPresent(Strategy.class)) {
Strategy stragtegyAnnotation = (Strategy) annotated.getAnnotation(Strategy.class);
switch(stragtegyAnnotation.value) {
case A: return new Controller(configA);
...
}
}
}
So, I'm not really familiar with EE6 annotations, but I solved a similar issue using pure Spring annotations in a question that I asked and then answered myself. It's not quite the same thing because it only creates once instance, but with all of the different dependencies injected into a Map. Basically, it will allow to switch implementations based on a config flag, but not instantiate all of them at once.
Related
I am looking into a codebase where every POJO has been managed by spring and injected using lookup annotation.
#Lookup
public Publisher getPublisher() {
return new Publisher();
}
#Lookup
public Book getBook() {
return new Book();
}
These Publisher and Book objects are nothing but POJO with just getter/setters. These classes are spring managed as prototype beans. I am thinking, it is over use of lookup annotation and overhead where we could just use factory methods or simply create new instance. Do you think using lookup annotation for this use case useful/efficient?
In a general way, making instances of a class some spring beans is not relevant if these beans never be needed to take advantage of Spring features and if these beans never be injected in other beans or never needs to inject other beans in their own instance.
#Lookup is the annotation-based way of the the old XML lookup-method attribute. Besides beans created with this annotation also have multiple limitations. For new projects I never use it.
As alternative as you need to declare beans in the java class the #Bean annotation that creates "not limited" beans should generally be favored instead of.
EDIT :
I wrote an answer to a very related question yesterday : Spring - is using new a bad practice?.
I just updated it to be more exhaustive.
In a modular Spring configured application, we use factory beans to provide bean instances across module boundaries.
For example, one module A may expose a bean instance by the name name. Another module B can then consume that bean via a declaration of the style
<bean id="nameBean" class="com.zfabrik.springframework.ComponentFactoryBean">
<property name="componentName" value="A/name" />
<property name="className" value="a.AInterface" />
</bean>
Note that modules have separated class loader hierarchies and the actual implementation class of A/name may not be visible in B. As if in OSGI (although this is NOT OSGi).
My goal is to provide A/name in a programmatic application context in B. However when trying
#Configuration
public static class AppContext {
#Bean AInterface nameBean() {
return lookup("A/name",AInterface.class);
}
}
(lookup does the actual instance retrieval) I see that Spring is trying to configure the returned instance. For example, it will attempt to resolve #Autowired properties of A/names's implementation class - which does not make sense in the context of B (and the deal of the lookup is to provide something fully configured anyway). Even, if I try
#Configuration
public static class AppContext {
#Bean(autowire=Autowire.NO) AInterface nameBean() {
return lookup("A/name",AInterface.class);
}
}
it will go about configuring the returned instance.
How can I provide a bean to the application context without spring touching its implementation instance?
EDIT: As suggested by Sotirios Delimanolis, returning the FactoryBean does AFAICT avoids Spring configuration of the returned instance.
The alternative code would look like this:
#Configuration
public static class AppContext {
#Bean FactoryBean<AInterface> nameBean() {
return new ComponentFactoryBean("A/name",AInterface.class);
}
}
It's not as cool as an #UntouchedBean annotation because of the FactoryBean in the return type, but it solves the problem.
#Sotirios: Please suggest as answer so that I can tag your suggestion accordingly.
/EDIT
Ok, just so it can be closed. The suggested and accepted answer is to return the factory bean.
I have a java class lets say 'class1' which basically holds a ConcurrentHashMap (to be used as a cache) and some functions to update and remove the entries in the map.This class is not designed to be a singleton class.
I was having a discussion with a colleague, but couldnt really decide due to a couple of posts i read on the internet.I am asking if it is okay to do this-
<bean id="reqrespCacheMgr1" class="gravity.applications.RFQService.reqrespgtwy.utility.ReqRespCacheManager" scope="singleton">
</bean>
<bean id="reqrespCacheMgr2" class="gravity.applications.RFQService.reqrespgtwy.utility.ReqRespCacheManager" scope="singleton">
</bean>
<bean id="reqrespCacheMgr3" class="gravity.applications.RFQService.reqrespgtwy.utility.ReqRespCacheManager" scope="singleton">
</bean>
I am basically trying to create 3 singleton instances of the same class..I think it doesnt really spoil the meaning of singleton-ness because we are talking about singleton scope in the spring bean factory context and not the class loader context.. I know there are alternate ways to do this.. Like having 3 concurrenthash maps in the same class and using only one singleton bean reference ,there by trying to create update and remove methods for 3 maps in the same class.
I hope i didnt make it confusing but all i wanna know is which is a good approach.I am afraid im making an improper use of design patterns..
Let me know if the question is unclear
It seems you need not a singleton but prototype
<bean id="reqrespCacheMgr" class="gravity.applications.RFQService.reqrespgtwy.utility.ReqRespCacheManager" scope="prototype" />
class B1 {
#Autowire
ReqRespCacheManager cacheManager;
}
class B2 {
#Autowire
ReqRespCacheManager cacheManager;
}
class B3 {
#Autowire
ReqRespCacheManager cacheManager;
}
All 3 beans will get a new instance of ReqRespCacheManager
Looks OK to me, as long as you only need to use those 3 instances for the entire lifecycle of your application. Are you aware that autowiring a single property wont work for this type?
You will need to use #Qualifier to assign a specific instance into your application beans:
public class FooBean {
#Inject
#Qualifier("reqrespCacheMgr3")
ReqRespCacheManager cacheManager;
}
Alternatively, you can collect all three into a single bean by injecting a List component of your type.
#Inject
List<ReqRespCacheManager> caches;
Hope that helps! Good luck, and dont forget to think 2 steps ahead.
Here is my Spring AOP configuration.
<bean id="myObject" class="com.madzone.learn.spring.aop.OriginalClass"></bean>
<bean id="aspect" class="com.madzone.learn.spring.aop.AspectClass"></bean>
<aop:config>
<aop:aspect ref="aspect">
<aop:declare-parents
types-matching="com.madzone.learn.spring.aop.OriginalClass+"
implement-interface="com.madzone.learn.spring.aop.IntroducedInterface"
default-impl="com.madzone.learn.spring.aop.IntroducedInterfaceImpl" />
</aop:aspect>
ApplicationContext context = new ClassPathXmlApplicationContext("myApp.xml");
Object myObject = context.getBean("myObject");
if (myObject instanceof OriginalClass) {
System.out.println("This is OriginalClass");
}
if(myObject instanceof IntroducedInterface) {
System.out.println("This is IntroducedInterface");
}
With this introduction I was able to call the methods in the IntroducedInterface. But, I was not able to access the OriginalClass' methods. In the code snippet above, I never got the 'This is OriginalClass' printed out.
From the definition of 'Introduction' I understood that the proxy that implements the new interface will extend from OriginalClass and make its' methods accessible too.
Am I missing something here? Can someone explain the reasons, if any?
PS:
The following is a picture from Spring in Action (3rd Edition) that depicts this.
From the definition of 'Introduction' I understood that the proxy that
implements the new interface will extend from OriginalClass and make
its' methods accessible too.
I'm not sure where you got that impression from. All of Spring AOP is built, by default, on JDK dynamic proxies, which only work for interfaces. It's impossible to proxy a concrete class. There is support in Spring for using CGLIB proxies in order to proxy classes instead, but its use is discouraged by the reference guide in favor of programming to interfaces to reduce coupling.
I have a spring bean that extends HibernateDaoSupport. I want this bean injected into my Controllers, but I do NOT want it to implement any interface. I just want to refer to the concrete class from within the rest of my code (not use the AopProxy perhaps?) Does anyone have a way of doing this?
<bean id="mySampleService" class="com.sample.MySampleService">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
#Autowired
private MySampleService mySampleService;
... getters and setters ....
I know it's a good idea to use the interface and that's the whole point of IoC, but PLEASE DON'T suggest I use the interface.
If class to be proxied (by transactional proxy in your case) implements any interface (InitializingBean implemented by HibernateDaoSupport in your case), Spring by default uses proxying strategy based on JDK dynamic proxies.
So, it creates a proxy of type InitializingBean, that, obviously, cannot be injected into a field of type MySampleService.
If you don't want to use interface you can override the strategy used by transactional aspect by declaring <tx:annotation-driven> with proxy-target-class = "true".
See also:
7.6 Proxying mechanisms
Check the following. Ensure you have CGLIB on your classpath.
http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch08s06.html
you can write everything including the mapped controller in the xml as beans, then you don't need to write interfaces.
otherwise, with using annotation you need to build interfaces to proxy them.