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
In Spring Boot, you can use appContext. getBeanDefinitionNames() to get all the beans loaded by the Spring container.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With