I want to find analog #PostConstruct spring annotation for external bean.
I don't have oportunity to change source code of this class and this class is final.
other words: how to invoke external method after bean constructing?
You can try init-method, i.e.:
<beans>
<bean id="yourBean" class="com.example.your.external.Class" init-method="yourExternalInitMethod"/>
</beans>
EDIT
Alternative solution might be implementing InitializingBean, but it's Spring-specific interface.
EDIT2.
You might want to take a look at Mkyong's tutorial about init-method and destroy-method.
If you can't change this class nor derive it, maybe a customized BeanPostProcessors would do the job ?
Related
I have a project where I use heavily autowiring, e.g.
#Component("componentA")
public class ComponentAImpl implements ComponentA
#Component("componentB")
public class ComponentBImpl implements ComponentB {
#Autowired
private ComponentA componentA;
}
But I want customer to extend all the classes, so ideally they would just add a single jar into the classpath the the extended class should be used instead of the original one.
What I think would be great if they could just set a different name for the bean, e.g.
#component("componentA-custom)
I just need some way to customize the autowire process to look for a bean with "-custom" at the end and load it instead of the original bean.
Is there any way to do that?
Any help appreciated.
Thank you,
Mariusz
I found a solution, there is
#Primary
annotation that can be used to specify that the custom code added should be loaded instead of the original code.
What you are looking for is something similiar to this.
This should help you solve your problem.
If you need to get the bean name, you can inject in an instance of applicationContext which will get you the correct bean name (through a reverse lookup). or force all beans (ComponentA and CustomImplementation) to implement BeanNameAware
What You are asking about can be done via #Qualifier annotation, but it cannot generate bean names dynamically.
To allow external beans, You will need to create XML configuration for this, as it overrides annotation - based configuration. Your customers would have to provide:
New beans
XML configuration for your application that uses the new beans.
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.
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.
Ok, so here is my use case:
I have the following classes each encapsulating an instance of the next one in line. So:
A -> B -> C -> D
eg: In class A, I have an instance of class B and in class B I have an instance of C and so on.
Well, I am trying to convert the loading\initialization\injection logic to a hybrid Spring system. The general idea being that B, C and D will need to more or less be ApplicationContextAware. By that I mean, that they will not actually implement that interface, but instead require the ApplicationContext as a constructor parameter. This way, in the hybrid approach (where the developer does not use Spring to initialize the instance) they must at least pass in the ApplicationContext so that additional beans may be wired. The problem is, that in order for the Spring container to load the beans, I now have to pass in the ApplicationContext in the XML. But as far as I can tell, there is no nice way to do this.
I tried something like this:
public class ApplicationContextPlaceholder implements ApplicationContextAware {
private ApplicationContext _applicationContext;
public void setApplicationContext( final ApplicationContext applicationContext ) throws BeansException {
_applicationContext = applicationContext;
}
public ApplicationContext getApplicationContext() {
return _applicationContext;
}
}
<bean id="a" class="com.company.A">
<constructor-arg>
<bean id="applicationContext" class="com.company.ApplicationContextPlaceholder" />
</constructor-arg>
</bean>
But obviously this doesn't make any sense, since ApplicationContextPlaceholder isn't really an ApplicationContext. I've also looked for ways to reference the context inside the XML, but I'm not finding anything.
Does anyone know of an elegant solution to this type of problem?
EDIT #1:
I was thinking about it, and I could have ApplicationContextPlaceholder also implement ApplicationContext and just delegate to the injected context and then it occurred to me that maybe, just maybe this was already in Spring...but as far as I can tell, no.
EDIT #2:
The reason each class needs an ApplicationContext is that if a dev wishes to override one of the classes in the chain (say, C for sake of argument). In this instance the child class of C will still need to load D via Spring.
Unless a class is providing additional plumbing functionality, you should avoid exposing the ApplicationContext. Quoting the Spring reference: in general you should avoid it, because it couples the code to Spring and does not follow the Inversion of Control style.
If you are providing additional functionality (maybe, for example, a factory class that uses the ApplicationContext to assemble objects), then it's prudent to implement ApplicationContextAware since your functionality is already tied to Spring.
If you've considered your dependency injection alternatives and have decided on injecting the ApplicationContext in your beans, your ApplicationContextPlaceholder class (I would stay away from a Placeholder prefix to avoid any confusion with Spring property placeholders) is certainly a solution. (Since it is your own class, why not extend ApplicationObjectSupport for additional functionality.)
This class will need to be defined and initialized in your configuration, for example:
<bean id="appCtxHolder" class="ApplicationContextHolder" />
Because ApplicationContextHolder implements ApplicationContextAware, Spring will inject the ApplicationContext into appCtxHolder when it is initialized. You can use it for constructor injection like:
<bean id="a" class="com.company.A">
<constructor-arg>
<bean factory-bean="appCtxHolder" factory-method="getApplicationContext" />
</constructor-arg>
</bean>
ApplicationContextPlaceholder could have everything static. In that case, you don't need to pass ApplicationContext around, when a API requests for a certain bean, you could check if its null and if it is, load it using the ApplicationContext from ApplicationContextPlaceholder. That's assuming a setter based injection, if you are doing constructor based, you could init beans in the contructor too.
I'm using annotation configuration and I currently cannot use request scope for my controller, but I need one of the bean that controller uses to be a prototype. So I figured the best way would be getting prototypes for a singleton controller via method injection.
But then I realized that Spring's method injection needs an abstract class so that I couldn't use my annotation configuration ...
Could please anybody tell me how to do that ? It seems to me that it is very common scenario, but currently it can be realized only via "request scope" of controller.
Or I'd have to make my controller ApplicationContextAware and get the bean from context. But can annotation-config #Controller be ApplicationContextAware ?
You can simply #Inject ApplicationContext ctx, but you need your other bean to be defined in the child context (dispatcher-servlet.xml) (you need that anyway). And then you can look it up.
There is no way to define lookup-method injection with annotations currently. There is an open issue about that. So for this particular controller you can use xml configuration to define the lookup-method.