Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get a list of instantiated beans from Spring?

I have several beans in my Spring context that have state, so I'd like to reset that state before/after unit tests.

My idea was to add a method to a helper class which just goes through all beans in the Spring context, checks for methods that are annotated with @Before or @After and invoke them.

How do I get a list of instantiated beans from the ApplicationContext?

Note: Solutions which simply iterate over all defined beans are useless because I have many lazy beans and some of them must not be instantiated because that would fail for some tests (i.e. I have a beans that need a java.sql.DataSource but the tests work because they don't need that bean).

like image 940
Aaron Digulla Avatar asked Feb 12 '13 09:02

Aaron Digulla


3 Answers

For example:

 public static List<Object> getInstantiatedSigletons(ApplicationContext ctx) {
            List<Object> singletons = new ArrayList<Object>();

            String[] all = ctx.getBeanDefinitionNames();

            ConfigurableListableBeanFactory clbf = ((AbstractApplicationContext) ctx).getBeanFactory();
            for (String name : all) {
                Object s = clbf.getSingleton(name);
                if (s != null)
                    singletons.add(s);
            }

            return singletons;

    }
like image 95
Jose Luis Martin Avatar answered Jan 05 '23 00:01

Jose Luis Martin


I had to improve it a little

@Resource
AbstractApplicationContext context;

@After
public void cleanup() {
    resetAllMocks();
}

private void resetAllMocks() {
    ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
    for (String name : context.getBeanDefinitionNames()) {
        Object bean = beanFactory.getSingleton(name);
        if (Mockito.mockingDetails(bean).isMock()) {
            Mockito.reset(bean);
        }
    }
}
like image 31
Stefan K. Avatar answered Jan 04 '23 22:01

Stefan K.


I am not sure whether this will help you or not.

You need to create your own annotation eg. MyAnnot. And place that annotation on the class which you want to get. And then using following code you might get the instantiated bean.

ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(MyAnnot.class));
for (BeanDefinition beanDefinition : scanner.findCandidateComponents("com.xxx.yyy")){
    System.out.println(beanDefinition.getBeanClassName());
}

This way you can get all the beans having your custom annotation.

like image 38
Japan Trivedi Avatar answered Jan 05 '23 00:01

Japan Trivedi