Question

I am trying to access a bean, which is annotated with @Component and initialized by Spring IoC. I have an abstract class which should return the correct concrete child class in a static method.

But I always facing NoSuchBeanDefinitionException.

I tested to @Autowired my OrderFactoryFinland in one of my @Controller classes, and it is correctly initialized by Spring IoC with all DAO fields.

So in my opinion, it should be somehow possible to access this Singleton instance in the static method?

Concrete sub class:

@Component
public class OrderFactoryFinland extends OrderFactory {
    @Autowired private TenantDao<Material> materialDao;
}

Abstract super class:

public abstract class OrderFactory {
    @Autowired protected UserService userService;

    public static OrderFactory getOrderFactory(Company company) throws Exception {
        ApplicationContext context = ApplicationContextProvider.getApplicationContext();
        Integer companyNumber = new Integer(company.getCompanyNumber());

        if (companyNumber.equals(SystemGlobals.COMPANY_NUMBER_FINLAND)) {
            return context.getBean(OrderFactoryFinland.class);
        } else if () {
            ...
        }
    }
}

Exception:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.xxx.yyy.order.fin.OrderFactoryFinland] is defined: expected single bean but found 0: 
Was it helpful?

Solution

You have to access the application context with the @Autowired annotation and not with a custom ApplicationContextProvider which implements ApplicationContextAware.

Now I have acccess to all my beans. So it seems that this was a timing problem.

private static ApplicationContext context;

@Autowired
public void setContext(ApplicationContext context) {
       OrderFactory.context = context;
}

OTHER TIPS

As the NoSuchBeanDefinitionException suggests, the error occurs because Spring fails to find the OrderFactoryFinland bean. Since it has been annotated with @Component, I guess that you intend to use component scanning to fetch it? Make sure that you have included the correct package. This applies regardless if you are using XML based configuration <context:component-scan ... > or Java based config @ComponentScan(...).

On a higher level, all Spring beans are by default Singelton Scope, which means that there is only one shared instance of each bean in Spring's application context that gets dependency injected. Springs way of doing this is based on object instances which means that you should use instance methods (as opposed to static class methods) for your logic. The reason for this approach is that this allows Spring to add proxies for various reasons (caching, security, etc) in a simple, consistent manner.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top