Spring Autowire during instantation? - spring

While refactoring an application and implementing injection via Spring it would be helpful to get hold of autowired objects within the instantiation phase. I cannot get it work (and would understand if it does not work at all; instatiation would be very tricky) but nevertheless want ot ask the question here to make sure.
For testing purposes I created this bean:
import org.springframework.stereotype.Repository;
#Repository
public class MyService {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
which is meant to become injected to this component:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import de.sample.spring.service.MyService;
#Component
public class MyComponent {
#Autowired
private MyService myService;
public MyComponent() {
System.out.println("MyService during instantiation="+myService);
showInternallyMyService();
}
#Autowired
private void setMyService(MyService myService) {
System.out.println("MyService during instantion via setter="+myService);
}
private void showInternallyMyService() {
System.out.println("MyService during instantiation via constructor call="+myService);
}
public void showWhenExternalCalledMyService() {
System.out.println("MyService when show has been called after instatiation="+myService);
}
}
The associated applicationContext is:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- enable autowire -->
<context:annotation-config />
<context:component-scan base-package="de.sample.spring.service" />
<context:component-scan base-package="de.sample.spring.component" />
</beans>
The stuff is then run by:
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import de.sample.spring.component.MyComponent;
public class Start {
private static final Logger LOGGER = LoggerFactory.getLogger(Start.class);
private final static String contextPath = "/context/applicationContext.xml";
public static void main(String[] args) throws IOException {
ApplicationContext context = null;
try {
context = new ClassPathXmlApplicationContext(contextPath);
} catch (Exception e) {
LOGGER.error("",e);
}
MyComponent myComponent = (MyComponent) context.getBean("myComponent");
myComponent.showWhenExternalCalledMyService();
}
}
The resulting log shows then these messages
MyService during instantiation=null
MyService during instantiation via constructor call=null
MyService during instantiation via setter=de.sample.spring.service.MyService#2ea227af
MyService when show has been called after instantiation=de.sample.spring.service.MyService#2ea227af
As can be seen the "Autowired" object is null in the constructor phase, only in the running phase it is instantiated. As already said - I think this is the way it is meant to work, but still I hope I'm wrong and can manage to get it work to access the autowired in the constructor. I know, I could use the constructor with properties - this would solve my problem but I wonder if it could be managed with another approach.

Beans get autowired after the constructor has been executed...per default.
If you want to autowire it at construction time you have to #autowire it at the constructor:
#Autowired
public MyComponent(MyService myService) {
System.out.println("MyService during intantiation="+myService);
showInternallyMyService();
}

You can try the way #watchme mentioned but take note that using this way will make it kind of immutable object but ensure that required dependencies are not null.
Also With #Autowired on a field you don't need a setter method for it and once your bean's constructor is done with allocating/creating the object,
Spring will scan for this annotation and would inject the object instances that you annotated.

This works as designed. During the initialization phase, beans are initialized and the dependency injection is done.
If you want to guarantee all dependencies have been injected, you should implement your logic in an initialization callback. Use the #PostConstruct annotation:
#Component
public class MyComponent {
#Autowired
private MyService myService;
public MyComponent() {
System.out.println("MyService during intantiation="+myService);
}
#Autowired
private void setMyService(MyService myService) {
System.out.println("MyService during instantion via setter="+myService);
}
#PostConstruct
private void showInternallyMyService() {
System.out.println("MyService during initialization="+myService);
}
}

Related

#Autowired is Null in Spring Boot but same is accessible through Application Context

Through #Autowired i am not able to access the #Component/#Service/#Respository/#Controller class objects in other java files which has #Component annotation (Step 1: Approach) with the Step 1 approach getting Null pointer Exception, but same i could achieve using (Step 2: Approach).
Can anyone please tell me why i am not able to achieve using Step 1 approach:
FYI- I've searched in my entire project i have not used/called/initialized the #Component classes using new method for the autowired class still i getting the issue as "Null Pointer Exception"
Step 1: Using #Autowired Annotation
#Component
public class Processor {
#Autowired
PropertyConfigurator propconfigrator; --> Getting here as null pointer Exception
public void getDetails(){
System.out.println ("Application URL +propconfigrator.getProperties().getProperty("appURL"));
}
}
Step 2: Using ApplicationContext Interface with/without #AutoWired annotation . I am able to get the property value from PropertyConfigurator java file
#Component
public class Processor {
#Autowired
PropertyConfigurator propconfigrator = ApplicationContextHolder.getContext().getBean(PropertyConfigurator.class);
public void getDetails(){
System.out.println ("Application URL +propconfigrator.getProperties().getProperty("appURL"));
}
}
ApplicationContextHolder.java
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
#Component
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext context;
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static ApplicationContext getContext() {
return context;
}
}
PropertyConfigurator.java file
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
#Service
#Configurable
public class PropertyConfigurator {
private final Properties properties;
public Properties getProperties () {
return properties;
}
public PropertyConfigurator(){
properties = new Properties();
try {
properties.load(getClass().getClassLoader().getResourceAsStream("dbconfig.properties"));
} catch (IOException e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, e.getMessage(), e);
}
}
}
Why did you use #Configurable annotation? In the code you postet, it doesn't make sense. #Configurable is only needed in cases when instances of this class are not createt by spring.
I have changed into Constructor Injection Autowiring as below with the step 1 approach of above (Not using Step 2. It resolved my issue finally.
Not sure why Spring is not able to inject the bean without using the Constructor Autowiring.
Step 1: Using #Autowired Annotation with Constructor
#Component
public class Processor {
#Autowired
public Processor (PropertyConfigurator propconfigrator) {
this.propconfigrator = propconfigrator;
}
public void getDetails(){
System.out.println ("Application URL +propconfigrator.getProperties().getProperty("appURL"));
}
}

Spring Boot : How to access repository in java class #Autowired not working

Spring Boot : How to access repository in java class #Autowired not working
Please explain your solution with sample code as I am new to Spring Boot.
Repository
import java.util.List;
import org.springframework.data.repository.CrudRepository;
public interface StoreRepository extends CrudRepository<Store, Integer> {
List<Store> findAll();
}
Entity Store
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class Store {
#Id
private Integer sid;
private String sname;
public Store() {
}
public Store(Integer sid, String sname) {
super();
this.sid = sid;
this.sname = sname;
}
///GETTER and Setters here...
}
**Store Service **
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class StoreService {
#Autowired
private StoreRepository storeRepository;
public StoreService() {
}
public List<Stores> getAllStores(){
return (List<Stores>) storeRepository.findAll(); /* This works good. Through controller I can retrieve all data*/
}
}
Simple Java class
#Component
public class StoreWorker {
#Autowired
private StoreRepository storeRepository;
public StoreWorker() {
System.out.println(storeRepository.findAll()); /* Error */
}
Error :
Exception in thread "StoreWorker : restartedMain" java.lang.reflect.InvocationTargetException
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.store.workers.StoreWorker]: Constructor threw exception; nested exception is java.lang.NullPointerException
Caused by: java.lang.NullPointerException
Please explain your solution with sample code as I am new to Spring Boot.
You have to change your code in this way:
If you want to use your autowired bean in the constructor of your class, use constructor injection. This is also the most recommended way of injection.
#Component
public class StoreWorker {
private final StoreRepository storeRepository;
public StoreWorker(StoreRepository storeRepository) {
this.storeRepository = storeRepository;
System.out.println(storeRepository.findAll());
}
}
So when the StoreWorker gets instantiated the autowired bean storeRepository gets injected. Since this happens you are able to use storeRepository bean.
You should not put any logic in the constructor. Constructor methods are just to initialize your instance.
Make the call to the storeRepository in a separate method.
#Component
public class StoreWorker {
#Autowired
private StoreRepository storeRepository;
public void findAll() {
System.out.println(storeRepository.findAll());
}
}
When Spring is calling your constructor, the context is not fully initialized, and since you don't use constructor injection, storeRepository is not injected yet.
Constructor injection is the recommended way to inject by the Spring team. And as of Spring 4.3, you don't even need to add the #Autowired annotation on constructors.
#Component
public class StoreWorker {
private StoreRepository storeRepository;
//#Autowired not needed since v4.3
public StoreWorker(StoreRepository storeRepository) {
this.storeRepository = storeRepository;
}
...
}
If you want to do further initialization of your bean relying on other external beans, do it in a separate method annotated with #PostConstruct.
#Component
public class StoreWorker {
private StoreRepository storeRepository;
private List<Store> stores;
public StoreWorker(StoreRepository storeRepository) {
this.storeRepository = storeRepository;
}
#PostConstruct
public void initializeMyBean() {
stores = storeRepository.findAll();
}
}
You should use #Autowire in the constructor level in order to use Autowire variable inside the constructor.
#Component
public class StoreWorker {
#Autowired
public StoreWorker(StoreRepository storeRepository) {
System.out.println(storeRepository.findAll());
}
(or) Use PostConstruct
Autowiring happens after the construction of an object. Therefore they will not be set until after the constructor has completed.
If you need to run some initialization code, you should be able to pull the code in the constructor into a method and annotate that method with #PostConstruct.

how to create two instance of bean use anotate [duplicate]

With an XML configured Spring bean factory, I can easily instantiate multiple instances of the same class with different parameters. How can I do the same with annotations? I would like something like this:
#Component(firstName="joe", lastName="smith")
#Component(firstName="mary", lastName="Williams")
public class Person { /* blah blah */ }
It's not possible. You get a duplicate exception.
It's also far from optimal with configuration data like this in your implementation classes.
If you want to use annotations, you can configure your class with Java config:
#Configuration
public class PersonConfig {
#Bean
public Person personOne() {
return new Person("Joe", "Smith");
}
#Bean
public Person personTwo() {
return new Person("Mary", "Williams");
}
}
Yes, you can do it with a help of your custom BeanFactoryPostProcessor implementation.
Here is a simple example.
Suppose we have two components. One is dependency for another.
First component:
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;
public class MyFirstComponent implements InitializingBean{
private MySecondComponent asd;
private MySecondComponent qwe;
public void afterPropertiesSet() throws Exception {
Assert.notNull(asd);
Assert.notNull(qwe);
}
public void setAsd(MySecondComponent asd) {
this.asd = asd;
}
public void setQwe(MySecondComponent qwe) {
this.qwe = qwe;
}
}
As you could see, there is nothing special about this component. It has dependency on two different instances of MySecondComponent.
Second component:
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
#Qualifier(value = "qwe, asd")
public class MySecondComponent implements FactoryBean {
public Object getObject() throws Exception {
return new MySecondComponent();
}
public Class getObjectType() {
return MySecondComponent.class;
}
public boolean isSingleton() {
return true;
}
}
It's a bit more tricky. Here are two things to explain. First one - #Qualifier - annotation which contains names of MySecondComponent beans. It's a standard one, but you are free to implement your own. You'll see a bit later why.
Second thing to mention is FactoryBean implementation. If bean implements this interface, it's intended to create some other instances. In our case it creates instances with MySecondComponent type.
The trickiest part is BeanFactoryPostProcessor implementation:
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
Map<String, Object> map = configurableListableBeanFactory.getBeansWithAnnotation(Qualifier.class);
for(Map.Entry<String,Object> entry : map.entrySet()){
createInstances(configurableListableBeanFactory, entry.getKey(), entry.getValue());
}
}
private void createInstances(
ConfigurableListableBeanFactory configurableListableBeanFactory,
String beanName,
Object bean){
Qualifier qualifier = bean.getClass().getAnnotation(Qualifier.class);
for(String name : extractNames(qualifier)){
Object newBean = configurableListableBeanFactory.getBean(beanName);
configurableListableBeanFactory.registerSingleton(name.trim(), newBean);
}
}
private String[] extractNames(Qualifier qualifier){
return qualifier.value().split(",");
}
}
What does it do? It goes through all beans annotated with #Qualifier, extract names from the annotation and then manually creates beans of this type with specified names.
Here is a Spring config:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="MyBeanFactoryPostProcessor"/>
<bean class="MySecondComponent"/>
<bean name="test" class="MyFirstComponent">
<property name="asd" ref="asd"/>
<property name="qwe" ref="qwe"/>
</bean>
</beans>
Last thing to notice here is although you can do it you shouldn't unless it is a must, because this is a not really natural way of configuration. If you have more than one instance of class, it's better to stick with XML configuration.
I just had to solve a similar case. This may work if you can redefine the class.
// This is not a #Component
public class Person {
}
#Component
public PersonOne extends Person {
public PersonOne() {
super("Joe", "Smith");
}
}
#Component
public PersonTwo extends Person {
public PersonTwo() {
super("Mary","Williams");
}
}
Then just use PersonOne or PersonTwo whenever you need to autowire a specific instance, everywhere else just use Person.
Inspired by wax's answer, the implementation can be safer and not skip other post-processing if definitions are added, not constructed singletons:
public interface MultiBeanFactory<T> { // N.B. should not implement FactoryBean
T getObject(String name) throws Exception;
Class<?> getObjectType();
Collection<String> getNames();
}
public class MultiBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
Map<String, MultiBeanFactory> factories = beanFactory.getBeansOfType(MultiBeanFactory.class);
for (Map.Entry<String, MultiBeanFactory> entry : factories.entrySet()) {
MultiBeanFactory factoryBean = entry.getValue();
for (String name : factoryBean.getNames()) {
BeanDefinition definition = BeanDefinitionBuilder
.genericBeanDefinition(factoryBean.getObjectType())
.setScope(BeanDefinition.SCOPE_SINGLETON)
.setFactoryMethod("getObject")
.addConstructorArgValue(name)
.getBeanDefinition();
definition.setFactoryBeanName(entry.getKey());
registry.registerBeanDefinition(entry.getKey() + "_" + name, definition);
}
}
}
}
#Configuration
public class Config {
#Bean
public static MultiBeanFactoryPostProcessor() {
return new MultiBeanFactoryPostProcessor();
}
#Bean
public MultiBeanFactory<Person> personFactory() {
return new MultiBeanFactory<Person>() {
public Person getObject(String name) throws Exception {
// ...
}
public Class<?> getObjectType() {
return Person.class;
}
public Collection<String> getNames() {
return Arrays.asList("Joe Smith", "Mary Williams");
}
};
}
}
The bean names could still come from anywhere, such as wax's #Qualifier example. There are various other properties on the bean definition, including the ability to inherit from the factory itself.
Continuing #espen answer, injecting beans with qualifiers and configuring them differently with external values.
public class Person{
#Configuration
public static class PersonConfig{
#Bean
//#Qualifier("personOne") - doesn't work - bean qualifier is method name
public Person personOne() {
return new Person("Joe", "Smith");
}
#Bean
//#Qualifier("personTwo") - doesn't work - bean qualifier is method name
public Person personTwo(#Value("${myapp.second.lastName}") String lastName) {
return new Person("Mary", lastName);
}
}
/* blah blah */
}
#Component
public class SomePersonReference{
#Autowired
#Qualifier("personTwo")
Person marry;
}
Should you need to inject, in the new created object, beans or properties from the spring context, you can have a look at the following section of code in which I have extended the Espen answer by injecting a bean which is created from the spring context:
#Configuration
public class PersonConfig {
#Autowired
private OtherBean other;
#Bean
public Person personOne() {
return new Person("Joe", "Smith", other);
}
}
Have a look at this article for all the possibile scenarios.

Spring factorybean error in Spring 3.1.1 but not in 3.1.0

I have a context file as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="aFactoryBean" class="com.kilo.SpecialFactoryBean"
factory-method="createInstance">
</bean>
</beans>
Loading the context of this is failing with an exception Exception in thread "main" org.springframework.beans.factory.BeanIsNotAFactoryException: Bean named 'aFactoryBean' must be of type [org.springframework.beans.factory.FactoryBean], but was actually of type [com.kilo.SpecialObject] when using Spring v 3.1.1.RELEASE whereas the same works fine with v 3.1.0.RELEASE. Thought that I might ask here if I am missing something obvious in configuring this, before falsely declaring this as a bug :)
SpecialFactoryBean.java
package com.kilo;
import org.springframework.beans.factory.FactoryBean;
public class SpecialFactoryBean implements FactoryBean<SpecialObject> {
private static SpecialObject ourInstance;
#Override
public SpecialObject getObject() throws Exception {
return ourInstance;
}
#Override
public Class<?> getObjectType() {
return SpecialObject.class;
}
#Override
public boolean isSingleton() {
return true;
}
public static SpecialObject createInstance() {
if (ourInstance == null) {
init();
}
return ourInstance;
}
private static void init() {
ourInstance = new SpecialObject();
}
}
SpecialObject.java
package com.kilo;
import org.apache.log4j.Logger;
public class SpecialObject {
private static final Logger LOG = Logger.getLogger(SpecialObject.class);
public void doSomething() {
LOG.info("Did something special");
}
}
SpringFBDriver.java
package com.kilo;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringFBDriver {
private static final Logger LOG = Logger.getLogger(SpringFBDriver.class);
private static ApplicationContext applicationContext;
public static void main(String[] args) {
applicationContext = new ClassPathXmlApplicationContext(
"classpath:com/kilo/applicationContext.xml");
LOG.info("Inited");
doSomething();
}
private static void doSomething() {
SpecialObject specialObject = applicationContext
.getBean(SpecialObject.class);
specialObject.doSomething();
}
}
Exception in thread "main" org.springframework.beans.factory.BeanIsNotAFactoryException: Bean named 'aFactoryBean' must be of type [org.springframework.beans.factory.FactoryBean], but was actually of type [com.kilo.SpecialObject]
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1420)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:305)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.kilo.SpringFBDriver.main(SpringFBDriver.java:15)
I think that you are confusing factory beans and Factory Beans as specified in the documentation.
In Spring documentation, factory bean refers to a bean that is
configured in the Spring container that will create objects through an
instance or static factory method. By contrast, FactoryBean (notice
the capitalization) refers to a Spring-specific FactoryBean .
Your class is already a FactoryBean so you don't need to specify it's method factory-method="createInstance" it reserved for factory beans - plain old beans that can create simple objects, not the FactoryBeans that are integrated to the bean definitions.

How do I enumerate all the BeanFactories in Spring?

Is there a way to discover all the BeanFactories defined by Spring programmatically. I want to create a status debug page which prints out the names and class types of every bean in the spring application context, however I don't know how to obtain a list of all the ApplicationContexts.
You can wire a BeanFactoryPostProcessor with your ApplicationContext that will allow you to traverse the BeanDefinition's of a passed ConfigurableListableBeanFactory which will represent all of the beans from your ApplicationContext.
With this instance of ConfigurableListableBeanFactory, you can find all beans of a type (getBeansOfType()), or all beans with a given annotation (getBeansWithAnnotation()), among other things.
You can use the ApplicationContext aware to do this.
#Component
public class PrintSpringBeansInContext implements ApplicationContextAware
{
private ApplicationContext applicationContext;
#Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException
{
this.applicationContext = applicationContext;
}
public void print()
{
String[] beanNames = this.applicationContext.getBeanDefinitionNames();
StringBuilder printBuilder = new StringBuilder("Spring Beans In Context: ");;
for(String beanName : beanNames)
{
printBuilder.append("\n");
printBuilder.append(" Bean Name: ");
printBuilder.append(beanName);
printBuilder.append(" Bean Class: ");
printBuilder.append(this.applicationContext.getBean(beanName).getClass());
}
System.out.println(printBuilder.toString());
}
}
You can test this
#ContextConfiguration(locations={"classpath:context.xml"})
#RunWith(SpringJUnit4ClassRunner.class)
public class PrintContextTest
{
#Autowired
private PrintSpringBeansInContext service;
#Test
public void printBeans()
{
Assert.assertNotNull(service);
service.print();
}
}
Code below is a Spring listener which can be registered with the main spring.xml file for the web application, it builds a map of all the child application contexts and exposes this map as a property. The class below can be injected into any spring bean that needs it using #Autowired.
import java.util.Hashtable;
import java.util.Map;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationContextEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.ContextStartedEvent;
public class ContextsApplicationListener implements ApplicationListener<ApplicationContextEvent> {
private Map<String,ApplicationContext> contextMap = new Hashtable<String,ApplicationContext>();
#Override
public void onApplicationEvent(ApplicationContextEvent event) {
if( event instanceof ContextStartedEvent || event instanceof ContextRefreshedEvent){
this.getContextMap().put(event.getApplicationContext().getDisplayName(), event.getApplicationContext());
}
}
public Map<String,ApplicationContext> getContextMap() {
return contextMap;
}
}
enter code here

Resources