public class PlatformEventFactory {
public PlatformEvent createEvent(String eventType) {
if (eventType.equals("deployment_activity")) {
return new UdeployEvent();
}
return null;
}
}
我有一个工厂类,它根据eventType创建PlatformEvent
类型对象。
在创建private RedisTemplate<String, Object> template
对象后,UdeployEvent类依赖于我想要注入的UdeployEvent
。
@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
返回新对象时,我得到模板的空指针异常。我相信原因是因为它不是指弹簧启动时创建的同一个bean。 如何在运行时为新创建的对象注入依赖项。
答案 0 :(得分:4)
您不应手动创建组件。让Spring来做这件事。使用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都会创建具有完全初始化依赖关系的组件的新实例。
答案 1 :(得分:1)
当您手动创建对象时,不会在创建的对象中执行依赖项注入,并且该字段为空。
简单的方法是使用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有更多的扩展解决方案,但是它们产生了大量的样板代码,并没有给予太多回报。
Haven在Spring中看不到更清洁的解决方案(比如Guice中的@AssistedInject)。
来源: http://www.kubrynski.com/2013/09/injecting-spring-dependencies-into-non.html
答案 2 :(得分:0)
你应该将你的bean注释为SCOPE_PROTOTYPE
,正如@ ken-bekov指出的那样。
要获取原型bean的实例,您可以使用注入(自动装配)org.springframework.beans.factory.ObjectProvider<T>
,而不是ApplicationContext
。此提供商的类型参数应为UdeployEvent
另外,您可以在get
方法中为类构造函数或工厂方法提供参数。这种方法的一个缺点是不会静态检查对get
的调用。
解决问题的另一种方法是尝试使用Google's AutoFactory。