Reputation: 3555
We use singleton service classes in our application:
public class LevelApprovalServiceImpl extends BaseBusinessServiceImpl implements LevelApprovalService {
/** There's one and only one instance of this class */
private static final LevelApprovalServiceImpl INSTANCE = new LevelApprovalServiceImpl();
/**
* Constructor is private, use getInstance to get
* an instance of this class
*/
private LevelApprovalServiceImpl() {
}
/**
* Returns the singleton instance of this class.
*
* @return the singleton instance of this class.
*/
public static LevelApprovalServiceImpl getInstance() {
return INSTANCE;
}
}
We recently upgraded Spring to Spring 5 and have started using the @Autowired annotation in our controllers:
@RestController
@RequestMapping("/approvals")
public class ApprovalRestController extends BaseRestController {
@Autowired
transient private LevelApprovalService levelApprovalService;
}
The problem is that due to this, our web application currently has 2 instances of every singleton service: the singleton we created ourselves and the singleton created by Spring. autowiring. We'd rather this not be the case and have a single singleton instance for everything.
Is there a way to tell Spring to use the getInstance() method of the singleton while still using Spring annotations to wire things together? Not every service is used in the Spring frontend, so we need to have Spring use our singleton instance instead of the other way around, and we'd rather not have to switch to xml-based configuration or start using a configuration file.
Upvotes: 1
Views: 171
Reputation: 1
You can create add your singleton instance to spring container as bean from configuration class:
@Configuration
public class MyConfig {
@Bean
public LevelApprovalServiceImpl service() {
return LevelApprovalServiceImpl.getInstance();
}
}
It would be right to choose either native singleton creation or Spring creation, btw your getInstance() is not thread-safe.
Upvotes: 0
Reputation: 49606
You can define a @Bean
method in one of your @Configuration
classes.
@Configuration
public class Configuration {
@Bean
public LevelApprovalService getLevelApprovalService() {
return LevelApprovalServiceImpl.getInstance();
}
}
This way, Spring will always be using the instance you have created.
Upvotes: 2