Reputation: 1237
At the office we are making spring maven web applications and set them up via a WebApplicationInitializer and the AnnotationConfigWebApplicationContext.
I have a task that involves initializing beans programmatically.
I have been trying to use the rootContext to get the bean factory and initialize custom beans manually, but it didn't work and it would tell me that no bean with that name was initialized in app context.
Here is my code :
public void onStartup(ServletContext sc) throws ServletException {
AnnotationConfigWebApplicationContext rootContext
= new AnnotationConfigWebApplicationContext();
// my method for adding beans to root context
registerBeansManually(rootContext,
new Class<?>[]{MyEntity1.class, MyEntity2.class},
Map<String,String> mapReadFromSomewhere);
sc.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext webContext
= new AnnotationConfigWebApplicationContext();
webContext.setParent(rootContext);
webContext.register(SpringWebConfig.class);
DispatcherServlet ds = new DispatcherServlet(webContext);
ServletRegistration.Dynamic registration = sc.addServlet("dispatcher1", ds);
registration.setLoadOnStartup(1);
registration.addMapping("/");
}
And in another method, i try to initialize the beans :
public void registerBeansManually(AnnotationConfigWebApplicationContext rootContext,
Class<?>[] entityClasses,
Map<String,String> dbInfoMap)
{
// get the bean factory from the root context
rootContext.refresh();
ConfigurableListableBeanFactory beenFactory = rootContext.getBeanFactory();
// in dbInfo map are the infor for connecting to db
// produce a DataSource instance and register it as a singleton bean :
DataSource ds = new DatabaseBeansProducer().produceDataSource(dbInfoMap);
beanFactory.registerSingleton("myProjectDataSource", ds);
// using the myProjectDataSource and the entity classes in the method argument
// produce a SessionFactory and register it as a singleton bean :
LocalSessionFactoryBean sf = new DatabaseBeansProducer().produceSessionFactory(ds, entityClasses);
beanFactory.registerSingleton("myProjectSessionFactory", sf);
// using the myProjectSessionFactory, produce the TransactionManager
// and register it as a singleton bean :
HibernateTransactionManager txm = new DatabaseBeansProducer().produceTransactionManager(sf);
beanFactory.registerSingleton("myProjectTransactionManager", txm);
}
Like I've said, I suffer from missing beans when I try to initialize them this way, namely, I get an error message saying that I can't @Autowire the 'myProjectSessionFactory' bean because no bean with that name exists in the app context.
How could I do this?
Upvotes: 0
Views: 467
Reputation: 1237
I figured it out :
All i have to do is to put the following annotation on the myProjectSessionFactory bean :
@Autowired(required=false)
@Qualifier("myProjectSessionFactory")
private SessionFactory sessionFactory;
And i do the same with any bean that complains about not being in the app context.
This is happening because when you do a
rootContext.refresh();
Spring will try to autowire all the beans within @ComponentScan, and it isn't finding a session factory, because i am initializing it in this savage manner later on.
Upvotes: 1