java - 如果可能的话,是否可以在请求范围内注入 bean,如果它对线程不活动,那么注入原型?
问题描述
我想将请求范围的bean注入单例范围。我可以使用Provider
. 当request
线程的范围没有处于非活动状态时,就会出现此问题。在这种情况下,我想在例如prototype
范围内注入 bean。那可能吗?例如代码:
public class Tenant {
private String name;
...
}
@Configuration
public class AppConfig {
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_REQUEST)
public Tenant prototypeBean() {
return new Tenant();
}
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Tenant prototypeBean() {
return new Tenant();
}
@Bean
public MySingletonBean singletonBean() {
return new MySingletonBean();
}
public class MySingletonBean {
@Autowired
private Provider<Tenant> beanProvider;
//inject conditionally on request or prototype scope
public void showMessage() {
Tenant bean = beanProvider.get();
}
}
我想避免此消息出错:
Error creating bean with name 'tenantDetails':
Scope 'request' is not active for the current thread;
consider defining a scoped proxy for this bean if you intend to
refer to it from a singleton;
nested exception is java.lang.IllegalStateException: No thread-bound
request found: Are you referring to request attributes outside of an
actual web request, or processing a request outside of the originally
receiving thread? If you are actually operating within a web request
and still receive this message, your code is probably running outside
of DispatcherServlet/DispatcherPortlet: In this case, use
RequestContextListener or RequestContextFilter to expose the current
request.
解决方案
如果需要这样的东西,那么应该重新考虑应用程序的设计。
可能吗?是的。
@Component
@RequestScope
public class RequestScopeTenant implements Tenant {
private String name;
...
}
这样我们就有了请求范围的bean。
@Component
@PrototypeScope
public class DefaultTenant implements Tenant {
private String name;
...
}
这里我们有我们的默认租户。
@Configuration
public class AppConfig {
@Primary
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Tenant prototypeBean(RequestScopeTenant requestScopeTenant, DefaultTenant defaultTenant) {
return RequestContextHolder.getRequestAttributes() != null ? requestScopeTenant : defaultTenant;
}
@Bean
public MySingletonBean singletonBean() {
return new MySingletonBean();
}
这样,当没有可用的请求范围时,将返回默认租户。
同样,如果您必须实现这样的东西 - 更改设计或创建自定义范围。
推荐阅读
- python - 在 pandas 中添加具有特定 dtype 的新列
- java - 由 optaplanner solver.solve() 产生的 ClassCastException
- amazon-web-services - 获取 EC2 Windows Server 中文件的可下载链接
- vb6 - 名称与现有模块、项目或对象库冲突
- python - Python - 具有多个重复标签的 xml 提取
- c++ - 有没有办法从另一个应用程序的控制台获取文本?
- java -
> 如果没有 @Provides-annotated 方法,则无法提供 - r - R中的多参数梯度下降
- python - 使用正则表达式模式解析 URL 列表
- jenkins - 使用基于角色的策略时如何限制特定的詹金斯工作