Reputation: 410
In a Spring Boot project, we access our non managed DAO classes through a static method:
MyDao myDao = DaoProvider.getMyDao();
We use this in Spring managed @Service
classes:
@Service
public class MyService {
public void foo() {
MyDao myDao = DaoProvider.getMyDao();
myDao.bar();
....
}
}
This makes it hard to write unit tests. Static mocks are no option, because they are slowing down our build pipeline.
We would rather have a solution with @Autowired
or constructor dependency and some kind of configuration, that decides which class to inject:
@Service
public class MyService {
@Autowired
MyDao myDao;
public void foo() {
myDao.bar();
....
}
}
Obviously, someone has to tell Spring what class to inject, because MyDao
is no Spring managed bean. Is there a way to do so?:
@Configuration
public class NonManagedSpringInjectionConfiguration {
@Bean
MyDao getMyDao() {
return DaoProvider.getMyDao();
}
}
Upvotes: 1
Views: 546
Reputation: 17510
If you don't want to turn your MyDao
into a Spring-managed Bean, your simpler and probably best option is to instead create the MyService
Spring-managed Bean programmatically instead of relying on @Service
annotation. First, just remove @Service
from MyService
and adjust its constructor to accept MyDao
:
public class MyService {
MyDao myDao;
public MyService(MyDao myDao) {
this.myDao = myDao;
}
public void foo() {
myDao.bar();
....
}
}
And now you just need to register a MyService
bean using @Bean
in a Configuration class as follows:
@Configuration
public class WhateverConfiguration {
@Bean
MyService myService() {
return new MyService(DaoProvider.getMyDao());
}
}
If instead there is a possibility to make MyDao
a Spring-managed Bean, then just keep your NonManagedSpringInjectionConfiguration
as is:
@Configuration
public class NonManagedSpringInjectionConfiguration {
@Bean
MyDao getMyDao() {
return DaoProvider.getMyDao();
}
}
But then rely on constructor injection instead of on @Autowired
. It makes MyService
easier to unit test and also explicitly defines that MyDao
is mandatory for MyService
to work properly. In this case you would keep @Service
and rely on Spring to instantiate it:
@Service
public class MyService {
MyDao myDao;
public MyService(MyDao myDao) {
this.myDao = myDao;
}
public void foo() {
myDao.bar();
....
}
}
Upvotes: 1
Reputation: 1736
You just have to specify the profil for example :
@Configuration
public class NonManagedSpringInjectionConfiguration {
@Bean
@Profile("dev")
MyDao getMyDao() {
return DaoProvider.getMyDao();
}
}
Upvotes: 1