Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get access to all spring beans of a given type

I have a Spring application (Spring Batch not web application). In a test class, I want to grab access to all of my beans of a given type.

I understand that in Spring you should generally use IOC and let the container inject your beans. However in this case, I want to loop through a variable number of beans that extend a given class (org.springframework.batch.item.database.JdbcCursorItemReader), and do something (want it to be a unit/integration test that just connects it to the database and reads 1 row, so we can confirm at test time that all of the JdbcCursorItemReader in the system have valid SQL and row mappers).

Problem 1) I can only get beans one at a time. I can have my class implement BeanFactoryAware to get a reference to my beanfactory. Then I can do beanFactory.getBean("name"); to get access to a single bean. How do I instead get ALL beans? I can loop through and drop the ones that aren't the class I want.. but somehow I need a list of all beans the beanfactory knows about or something.

Problem 2) The bean I get back from the beanfactory is a proxy. If I try to cast and use my bean I get something like java.lang.ClassCastException: $Proxy0 cannot be cast to org.springframework.batch.item.database.JdbcCursorItemReader

like image 576
bwawok Avatar asked Oct 09 '10 16:10

bwawok


People also ask

How can we get list of all beans used in Spring application?

In Spring Boot, you can use appContext. getBeanDefinitionNames() to get all the beans loaded by the Spring container.

How do you get the BeanFactory reference in any class?

I can have my class implement BeanFactoryAware to get a reference to my beanfactory. Then I can do beanFactory. getBean("name"); to get access to a single bean.

How can I get specific beans in Spring boot?

Ways to get loaded beans in Spring / Spring boot ApplicationContext. getBeanDefinitionNames() will return names of beans which is correctly loaded. getBean(String name) method using that we can get particular bean using bean name. * Created by JavaDeveloperZone on 07-13-2019.

What is the @bean annotation?

One of the most important annotations in spring is the @Bean annotation which is applied on a method to specify that it returns a bean to be managed by Spring context. Spring Bean annotation is usually declared in Configuration classes methods. This annotation is also a part of the spring core framework.


1 Answers

You can get around the first problem by using ApplicationContextAware instead of BeanFactoryAware. This will pass in the ApplicationContext, which has the getBeansOfType() method which lets you retrieve all beans that are of a given type.

The second problem is likely caused because something is creating AOP proxies around your JdbcCursorItemReader bean. These generated proxies will, by default, implement the same interfaces that JdbcCursorItemReader does (specifically, ItemReader and ItemStream). Your code should not try and cast to the class type (JdbcCursorItemReader), but to one of those interface types instead. It's usually possible to force the proxy to extend the proxied class directly, but without knowing anything about your setup, I can't help you with that.

like image 116
skaffman Avatar answered Sep 20 '22 21:09

skaffman