如何仅在web请求中@Autowire一个RequestScoped bean



最近,我知道RequestScoped bean在web事务之外是不可用的。

问题是,在web事务之外,我不想使用那个bean,而不是出现错误。

我怎样才能做到这一点?

使用请求作用域bean的组件:

@Component
public class JavaComponent {
@Autowired
private RequestScopedBean requestScopedBean;

@Override
public void doStuff() {
// TODO if in web transaction, use RequestScopedBean , otherwhise don't
}
}

豆子:

@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestScopedBean {
public String getInfo() {
return "information about the web transaction";
}
}

编辑:当我尝试在web请求之外使用JavaComponent时,得到的错误是:

org.springframework.beans.factory.BeanCreationException:错误正在创建名为"JavaComponent.requestScopedBean"的bean:Scope"request"对于当前线程不是活动的;考虑定义如果您打算从单身;嵌套异常为java.lang.IollegalStateException:否找到绑定线程的请求:你指的是请求属性吗在实际web请求之外,或在最初的接收线程?如果您实际在一个web请求,但仍然收到此消息,您的代码可能是在DispatcherServlet/DispatcherPortlet之外运行:在这种情况下,使用RequestContextListener或RequestContextFilter公开当前请求。

在web请求线程之外使用bean的方式是让@Async方法在分离的线程中运行。

仅自动连线ApplicationContext并查找请求范围的bean,然后执行null检查。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
@Service
public class TestService {
@Autowired
private ApplicationContext applicationContext;
public void myMethod() {
RequestScopedBean bean = applicationContext.getBean(RequestScopedBean.class);
if (bean != null) {
// do stuff
}
} 
}

我想出了一个更好的解决方案,因为applicationContext.getBean((在调用时会抛出异常,相反,最好检查当前线程是否在web请求上下文中执行,然后获取bean。

我还测试了性能,get bean非常快(0ms(,可能是因为请求范围的bean非常轻

/**
* The Class AuditConfig.
*/
@Component
public class AuditConfig implements AuditorAware<String> {
/**
* The Constant SYSTEM_ACCOUNT.
*/
public static final String SYSTEM_ACCOUNT = "system";
@Autowired
private ApplicationContext context;
/**
* Gets the current auditor.
*
* @return the current auditor
*/
@Override
public Optional<String> getCurrentAuditor() {
return Optional.ofNullable(getAlternativeUser());
}
private String getAlternativeUser() {
try {
// thread scoped context has this != null
if (RequestContextHolder.getRequestAttributes() != null) {
Object userBean = context.getBean(AuditRequestScopedBean.BEAN_NAME);
if (StringUtils.isNotBlank(((AuditRequestScopedBean) userBean).getUser())) 
{
return ((AuditRequestScopedBean) userBean).getUser();
}
}
} catch (Exception e) {
return SYSTEM_ACCOUNT;
}
return SYSTEM_ACCOUNT;
}
}

最新更新