我正在用Spring Boot 1.5.8编写一个项目。 我有一些生成的实体类,包含bean(例如FooBean),它只存在于请求范围内。重要的是:我无法改变代码的这一部分。所以假设我有一个Entty:
@Enitty
public class FooEntity{
@Transient protected FooBean fooBean;
}
和FooBean实现:
@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class FooBean {
...
}
我也有一些代码的部分,其中我有方法应该由Spring CRON运行:
@Scheduled(cron = "0 0/2 * * * ?")
@Transactional(value = Transactional.TxType.REQUIRES_NEW)
void scheduledTask() {
...
}
重要的是:在那个scheduledTask中我将一些FooEntity实例保存到DB。 当然:当我尝试调用repository.saveAll()时,Spring会抛出异常:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.fooBean ': Scope 'request' is not active for the current thread;
有没有可能解决这个问题?如何覆盖此作用域bean,以便它可以在非请求范围内使用?
答案 0 :(得分:1)
我想稍后再写:),但是您可以创建自己的bean实例。 在春季启动中,您可以像这样简单地创建自己的bean单例实例:
@Configuration
@EnableScheduling
public class ApiConfig {
@Bean
@Primary
public FooBean fooBean(){
return new FooBean();
}
}
如果您的bean在必须自动装配的构造函数中有某些依赖关系(构造函数自动装配),则只需将这些bean放入方法params中,spring就会为您提供此类服务:
@Bean
@Primary
public FooBean fooBean(BeanToAutowire myBean){
return new FooBean(myBean);
}
如果您的bean没有构造函数自动关联的依赖项,而是注释自动关联的(使用@Autowired),则可以像下面这样简单地完成它:
@Bean
@Primary
public FooBean fooBean(AutowireCapableBeanFactory beanFactory){
FooBean bean = new FooBean(myBean);
beanFactory.autowireBean(bean); // here spring will autowire all dependencies for you
return bean;
}
这不是最优雅的方法,但是可以。副作用是在应用程序上下文中将有两个FooBean实例,但是spring将使用您的实例,因为您使用@Primary注释将此实例设置为主实例。只有将Autowired注释与限定符注释一起使用的bean才可以选择将FooBean的实例进行自动接线。