I'm writing a RESTful web service using Spring MVC, using Java Configuration. My configuration file is below. My issue is this -- I discovered that 2 instances of "myService" bean is being created, instead of just one instance. I'm not sure why? How can I adjust the configuration to create only one?
Can anyone point me in the right direction? Thanks!
Here's my configuration class....
@Configuration
public class MyConfig {
@Bean(name = "dataSource")
public DriverManagerDataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
// datasource set up
return dataSource;
}
@Autowired
@Bean(name = "sessionFactory")
public SessionFactory getSessionFactory(DriverManagerDataSource dataSource) {
LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource);
sessionBuilder.scanPackages("com.mypackages");
sessionBuilder.addProperties(getHibernateProperties());
return sessionBuilder.buildSessionFactory();
}
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.enable_lazy_load_no_trans", "true");
properties.put("hibernate.id.new_generator_mappings", "true");
return properties;
}
@Autowired
@Bean(name = "transactionManager")
public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
return transactionManager;
}
@Bean
public MyMainBean MyMainBean() {
MyMainBean bean = new MyMainBean();
bean.setService(myService());
bean.setValidator(myValidator());
return bean;
}
@Bean(name = "myService")
public MyService myService() {
MyService s = new MyService();
s.setDao1(myDao1());
s.setDao2(myDao2());
s.setCopyUtil(copyUtil());
return s;
}
@Bean
public MyDao1 myDao1() {
return new MyDao1();
}
@Bean
public MyDao2 myDao2() {
return new MyDao2();
}
@Bean
public CopyUtil copyUtil() {
return new CopyUtil();
}
@Bean
public ReportValidator reportValidator() {
ReportValidator validator = new ReportValidator();
validator.setService(myService());
return validator;
}
@Bean
public XMLValidator xmlValidator() {
XMLValidator validator = new XMLValidator();
validator.setService(myService());
return validator;
}
}
Actually, Spring is smart when wiring beans and should only call the myService()
function once , and then pass the result to the other myService()
calls, resulting in only one bean of MyService
.
Make sure you really are getting 2 instances of MyService
, eg by adding a log in the constructor of the MyService
class.
If you truly see more than one constructor log statement, make sure that you are not declaring other MyService
beans in other @Configuration
classes, or that you are not using any component annotation on the MyService
class (ie don't use @Service
, @Component
, @Repository
).
If you declare the class with @Service
, it effectively instantiates the class and adds it to the context. When you declare it again with @Bean
you end up with 2 instances , so don't mix them.
Also, you don't need to use those @Autowired
annotations here, or even calls to other beans, because the following will also work:
@Configuration
public class DbConfiguration {
@Bean
public MovieDao dao() {
return new MovieDao();
}
@Bean
public MovieService service(MovieDao dao) {
return new MovieService(dao);
}
}
Spring will see that you need a MovieDao
to build a MovieService
and it will instantiate the dao first and pass it to the service bean. You don't even need to add @Service
or similar annotations to your classes!
It really is that good, hope these tips help ;)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.