我试图更好地理解如何在我的应用程序中实现构造函数注入。我有一些后台进程由SimpleMessageListenerContainer工作程序执行,它们从AMQP服务器中提取消息。
我的应用程序包含服务层和repo层,worker使用服务进行数据读/写。我的控制器,服务和repos都是使用构造函数注入设置的,但是由于需要实例化新版本的worker,我仍然坚持如何初始化worker。
工人
public class RandomWorker extends Worker {
private UserService userService;
@Autowired
public RandomWorker(UserService userService) {
this.userService = userService;
}
@Override
public byte[] handleMessage(byte[] message) {
... do work ...
}
}
服务层
@Service
public class UserService {
private SecurityAreaRepo securityAreaRepo;
private SecurityRoleRepo securityRoleRepo;
private UserRepo userRepo;
@Autowired
public UserService(SecurityAreaRepo securityAreaRepo,
SecurityRoleRepo securityRoleRepo,
UserRepo userComponent) {
this.securityAreaRepo = securityAreaRepo;
this.securityRoleRepo = securityRoleRepo;
this.userRepo = userRepo;
}
}
WorkerConfig
@Configuration
public class WorkerConfig {
@Bean
public RandomWorker randomWorker() {
return new RandomWorker();
}
@Bean(name="randomWorkerContainer")
public SimpleMessageListenerContainer randomWorkerContainer() {
SimpleMessageListenerContainer smlc = new SimpleMessageListenerContainer();
smlc.setConnectionFactory(connectionFactory());
smlc.setMessageListener(new MessageListenerAdapter(randomWorker(), "handleMessage"));
smlc.setQueueNames("random.worker.queue");
smlc.setConcurrentConsumers(5);
smlc.start();
return smlc;
}
}
由于我的worker需要UserService,所以当我初始化一个新的RandomWorker时,我必须在WorkerConfig中提供一个这样的实例。那么我是否必须为所有工作人员使用的所有服务创建一个@Bean?我的WorkerConfig看起来像这样:
@Configuration
public class WorkerConfig {
@Bean
public UserService userService() {
return new UserService(new SecurityAreaRepo(), new SecurityRoleRepo(), new UserRepo());
}
@Bean
public RandomWorker randomWorker() {
return new RandomWorker(userService());
}
@Bean(name="randomWorkerContainer")
public SimpleMessageListenerContainer randomWorkerContainer() {
SimpleMessageListenerContainer smlc = new SimpleMessageListenerContainer();
smlc.setConnectionFactory(connectionFactory());
smlc.setMessageListener(new MessageListenerAdapter(randomWorker(), "handleMessage"));
smlc.setQueueNames("random.worker.queue");
smlc.setConcurrentConsumers(5);
smlc.start();
return smlc;
}
}
如果是这种情况,我只是没有看到构造函数注入的重点,当字段注入使一切变得如此简单。有人可以对此有所了解吗?
答案 0 :(得分:1)
如果将bean指定为bean方法的参数,则Spring会自动注入依赖项。在您的情况下,您只需要将您的工作bean方法修改为:
@Bean
public RandomWorker randomWorker(UserService userService) {
return new RandomWorker(userService);
}
如果UserService
服务在上下文中可用,Spring会自动将其注入userService
参数。您不需要为每个服务使用@Bean
方法 - 在上下文中注册bean的任何方法都可以工作(例如@ComponentScan,@ SpringBootApplication甚至手动将bean添加到上下文中)。使用构造函数或setter注入无关紧要。
作为旁注 - 构造函数注入更好,因为您可以确保您的对象始终在有效状态下实例化。将所有对象始终保持在有效状态通常是一种很好的设计。