public class PlatformEventFactory {
public PlatformEvent createEvent(String eventType) {
if (eventType.equals("deployment_activity")) {
return new UdeployEvent();
}
return null;
}
}
我有一个工厂类,它根据 eventType 创建PlatformEvent
类型对象。
UdeployEvent 类依赖于创建UdeployEvent
对象后我要注入的private RedisTemplate<String, Object> template
。
@Component
public class UdeployEvent implements PlatformEvent {
private RedisTemplate<String, Object> template;
private UDeployMessage uDeployMessage;
private static final Logger logger = LoggerFactory.getLogger(UdeployEvent.class);
public UdeployEvent() {
uDeployMessage = new UDeployMessage();
}
/*public void sendNotification() {
}*/
public RedisTemplate<String, Object> getTemplate() {
return template;
}
@Autowired
public void setTemplate(RedisTemplate<String, Object> template) {
this.template = template;
System.out.println("Injection done");
}
}
当返回新对象时UdeployEvent
我得到模板的空指针异常。我相信这样做的原因是因为它不是指春天启动时产生的豆子。如何在运行时为新创建的对象注入依赖项。
不应手动创建组件。让春天来做这件事。使用 ApplicationContext
获取组件的实例。所有字段将自动注入:
@Component
public class PlatformEventFactory {
@Autowired
private ApplicationContext context;
public PlatformEvent createEvent(String eventType) {
if (eventType.equals("deployment_activity")) {
return context.getBean(UdeployEvent.class);
}
return null;
}
}
要使 Spring 在每次请求组件时创建组件的新实例UdeployEvent
请将组件的范围指定为 SCOPE_PROTOTYPE
:
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class UdeployEvent implements PlatformEvent {
private RedisTemplate<String, Object> template;
public RedisTemplate<String, Object> getTemplate() {
return template;
}
@Autowired
public void setTemplate(RedisTemplate<String, Object> template) {
this.template = template;
System.out.println("Injection done");
}
...
}
现在,每次调用context.getBean(UdeployEvent.class)
Spring都会创建具有完全初始化依赖项的组件的新实例。
手动创建对象时,不会在创建的对象中执行依赖项注入,并且字段为 null。
最简单的方法是使用AutowireCapableBeanFactory
autowireBean()
例:
@Component
public class PlatformEventFactory {
@Autowired
private AutowireCapableBeanFactory beanFactory;
public PlatformEvent createEvent(String eventType) {
if (eventType.equals("deployment_activity")) {
PlatformEvent platformEvent = new UdeployEvent();
beanFactory.autowireBean(platformEvent);
return platformEvent;
}
return null;
}
}
beanFactory.autowireBean(platformEvent)
应该注入您的田地,它应该可以正常工作。
@Configuration有更多的扩展解决方案,但它们会产生大量样板代码,并且不会提供太多回报。
在春天没有看到更清洁的解决方案(如Guice的@AssistedInject(。
源:http://www.kubrynski.com/2013/09/injecting-spring-dependencies-into-non.html
你应该把你的豆子注释为SCOPE_PROTOTYPE
,正如@ken-bekov指出的那样。
要获得原型 Bean 的实例,您可以使用注入(自动连线(org.springframework.beans.factory.ObjectProvider<T>
,而不是 ApplicationContext
。此提供程序的类型参数应为 UdeployEvent
。
此外,还可以get
方法中为类构造函数或工厂方法提供参数。这种方法的一个缺点是不会静态检查对get
的调用。
解决问题的另一种方法是尝试使用Google的AutoFactory。