How to get Spring Context - java

I have a third party library that starting up my aplication, load spring context and save it in private static filed without any acessors.
I need to get this context to my application. Does spring provides some callbacks like afterContextLoaded methods or any other ways how to get it?
Reflection is not a solution for me!
Thanks.

you have several ways to archive that:
Use ApplicationListerner and ApplicatinEvent
Use ApplicationContextAware
Both of them can be found at http://static.springsource.org/spring/docs/3.0.0.M4/reference/html/ch03s13.html
(sorry for the link is not to the latest version)

Just implement ApplicationContextAware in a Spring bean.
If you want to access the AppContext on startup, then also implement InitializingBean and put your code in afterPropertiesSet() - the ApplicationContext instance will be populated and ready for use at that time.

Related

How to get property file in a Configuration class implementing BeanDefinitionRegistryPostProcessor in spring boot

I have a Configuration class that is implementing BeanDefinitionRegistryPostProcessor , In this I have to take some properties from the Property file use them in the postProcessBeanDefinitonRegistry. When I try to autowire the ApplicationContext I noticed that the ApplicationContext object is coming as null and so does all the other injected objects. On looking into the explanation for "BeanDefinitionRegistryPostProcessor" I came to know that it executes early.
Question is :: How do I read my property values in the class that is implementing BeanDefinitionRegistryPostProcessor?
I have resolved the above issue. I understood that for my code logic "BeanDefinitionRegistryPostProcessor" is not suitable. For my scenario I had to implement the "ApplicationContextAware" interface.

#SpringBean support for bean in child ApplicationContext

I'm working with the developer of PF4J(Plugin Framework for Java) to provide better plugin functionality for Wicket. There is already a pf4j-spring and a pf4j-wicket project to provide some basic integration. In order to allow the #SpringBean or #Inject annotations to have access to plugin beans in a child context we need to be able to lookup the ApplicationContext associated with a specific class.
So for example, say I have a MyService bean in a child(plugin) ApplicationContext and that plugin also provides a panel that needs that via a #SpringBean annotation. Spring doesn't allow the parent ApplicationContext to see beans in a child context and for good reason. So we would get an exception saying that bean could not be found since #SpringBean only looks up beans in the parent context. We have code that we have developed that look up the child context like so:
SpringPlugin plugin = (SpringPlugin)PluginManager.whichPlugin(MyService.class);
ApplicationContext pluginContext = plugin.getApplicationContext();
How could I modify or provide this functionality in a custom version of SpringComponentInjector? It uses a ISpringContextLocator but that context locator does not specify the class for which it needs the ApplicationContext.
Any ideas on how this could be achieved?
Thanks for your help!
I'm afraid current SpringComponentInjector is not prepared for such usage. You will have to create your own version.
The problem that I see is that you will have to have either as many IComponentInstantiationListeners as plugins there are. Or create a composite ICIL that delegates to SpringBeanLocators for each plugin. I think the composite would be better. Then you'll have to make sure that a Panel in pluginA cannot use a bean located by SpringBeanLocatorB.
If you manage to do it and you find something in wicket-spring that could be made more generic to help make your version simpler then please let us know and we will consider your suggestion(s)!
Take a look at sbp. It is built on top of pf4j to support Spring Boot, and also provides mechanism of sharing beans between main application and plugins. It looks like:
#Override
protected SpringBootstrap createSpringBootstrap() {
return new SharedDataSourceSpringBootstrap(this, MdSimplePluginStarter.class)
.addSharedBeanName("objectMapper")
.addSharedBeanName("cacheService");
}

What is the proper way to have a "singleton" in Spring 4?

I have a java file "DatabaseMan.java" that helps connect to a database and connects helper functions. How can I make it such that it is created once for the life of my spring application, and I can call of its methods "getAllRows" for example, in each of my other resource classes?
Should I be declaring a bean in my Application.java or using some sort of annotation on my "DatabaseMan" class to indicate that it is "injectable"/"resusable"?
I see the following Spring3 example:
http://www.mkyong.com/spring3/spring-3-javaconfig-example/
The issue is, do I have to include this within every single resource:
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
HelloWorld obj = (HelloWorld) context.getBean("helloBean");
obj.printHelloWorld("Spring3 Java Config");
Is there a better way to get to the "HelloWorld" with less code and more annotation in Spring 4?
Remember, the ApplicationContext is a container to manage all your beans and their inter-dependencies. It is the entry point to your application. Once you've set it up, all the managed objects are linked up and ready to go.
Is there a better way to get to the "HelloWorld" with less code and more annotation in Spring 4?
It depends where you want to get it. If you want to get it from outside the ApplicationContext, then you need to do what you did. If you want to get into another bean, just inject it and the ApplicationContext will do the rest.
#Component
class SomeOtherBean {
#Autowired
private HelloWorld helloWorldBean;
// do something with it
}

Abstract class variable with spring

I am using spring and Hibernate and Dao design pattern for the my project, In my GenericDaoImpl(Abstract class) class has "tenentId", I want to set the "tenentId" when use login to the System. My other DaoImpl classes extends from GenericDaoImpl, so I need to set the tenentId(It's define in GenericDaoImpl) user login time and reset the "tenentId" when user log out.
What is the best way to do this?
In my test cases I tried #Autowired the "GenericDaoImpl" but I couldn't do that, It throws an exception telling, org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type. I know the problem now,
(We can't create instance of abstract classes,if use tenantId as static variable, is it going to be a problem?)
Can any one suggest me any solution?
Thank you,
Udeshika
if you are developing multi-tenancy application and would like to have tenant aware application context then have a look spring-tenancy. This will help you to have beans injected which are tenant aware.
if you want to multi-tenancy at hibernate layer then you can also look at multi-tenancy feature of hibernate.

is there an elegant way to inject a spring managed bean into a java custom/simple tag

I have a bunch of java custom tags that use spring managed beans.. since i cant find a way to inject into a custom tag, i created a helper class that provides static methods to "getTheObjectINeedBean()" for all the spring bean objects i need.. I do not like this approach at all.
i really want to be able to inject a spring managed bean into the custom tag
Is there a way? As far as my research goes, I understand there is no way to do this, because the custom tag is container managed
Thanks,
Billy
You are correct there isn't a simple way to use dependency-injection in jstl tags, because they are not managed by spring, and cannot be. However there are (at least) two workarounds:
#Configurable - aspectJ allows you to plug a weaver at load-time/compile-time, so that even objects that are not instantiated by spring can be spring aware. See here
You can create a base tag class for your project, and call an init(..) method from every doStartTag(..) method. There, you can get the ServletContext from the pageContext, and thus obtain the spring ApplicationContext (via ApplicationContextUtils). Then:
AutowireCapableBeanFactory factory = appCtx.getAutowireCapableBeanFactory();
factory.autowireBean(this);
Neither options are perfect as they require either some additional code, or some "black magic"
To expand on #Bozho's post, I have gotten this to work like so: (in spring 3.0 there is no ApplicationContextUtils that I could find)
public class LocationTag extends RequestContextAwareTag {
#Autowired
PathComponent path;
...
#Override
protected int doStartTagInternal() throws Exception {
if (path == null) {
log.debug("Autowiring the bean");
WebApplicationContext wac = getRequestContext().getWebApplicationContext();
AutowireCapableBeanFactory acbf = wac.getAutowireCapableBeanFactory();
acbf.autowireBean(this);
}
return SKIP_BODY;
}
}
The solution as described above works but some background and additional code snippets are, quite likely, useful.
1) The doStartTagInternal method is invoked from the doStartTag method.
2) I was forced to set the pageContext first before invoking the doStartTag
3) I did a lookup of the bean as opposed to the autowiring. To me this seems more straightforward: (YourBeanProxy) autowireCapableBeanFactory.getBean("yourBeanName")
Hopefully this additional info is useful.

Categories