Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何仅在web请求中@Autowire RequestScope bean_Java_Spring_Spring Boot_Dependency Injection - Fatal编程技术网

Java 如何仅在web请求中@Autowire RequestScope bean

Java 如何仅在web请求中@Autowire RequestScope bean,java,spring,spring-boot,dependency-injection,Java,Spring,Spring Boot,Dependency Injection,最近,我了解到RequestScope bean在web事务之外是不可用的 问题是,在web事务之外,我不想使用该bean,而不是出现错误 我怎样才能做到这一点 使用请求范围bean的组件: @Component public class JavaComponent { @Autowired private RequestScopedBean requestScopedBean; @Override public void doStuff() {

最近,我了解到RequestScope 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:范围 对于当前线程,“请求”未处于活动状态;考虑定义一个 如果您打算从一个目录引用此bean,则此bean的作用域代理 独生子女;嵌套异常为java.lang.IllegalStateException:否 找到线程绑定请求:您是指请求属性吗 在实际web请求之外,或在外部处理请求 最初的接收线程?如果你实际上是在 当您收到web请求并且仍然收到此消息时,您的代码可能是 在DispatcherServlet/DispatcherPortlet之外运行:在这种情况下, 使用RequestContextListener或RequestContextFilter公开 当前请求


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

Autowire
ApplicationContext
仅查找请求范围的bean,然后执行空检查

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;
    }

}
/**
*类AuditConfig。
*/
@组成部分
公共类AuditConfig实现AuditorAware{
/**
*常量系统是一个帐户。
*/
公共静态最终字符串SYSTEM\u ACCOUNT=“SYSTEM”;
@自动连线
私有应用程序上下文上下文;
/**
*获取当前审计员。
*
*@返回当前审计员
*/
@凌驾
公共可选getCurrentAuditor(){
返回可选的.ofNullable(getAlternativeUser());
}
私有字符串getAlternativeUser(){
试一试{
//线程作用域上下文具有此!=null
if(RequestContextHolder.getRequestAttributes()!=null){
Object userBean=context.getBean(AuditRequestScopedBean.BEAN\u名称);
if(StringUtils.isNotBlank(((AuditRequestScopedBean)userBean).getUser())
{
return((AuditRequestScopedBean)userBean.getUser();
}
}
}捕获(例外e){
返回系统账户;
}
返回系统账户;
}
}

您遇到了什么错误?另外,在Web请求的上下文之外使用
JavaComponent
的用例是什么?我已经用您的问题的答案编辑了这个问题。谢谢这回答了你的问题吗?不,我不想在异步请求中使用请求范围的bean,我只想在web请求之外不使用它。我理解这一点。使用
proxyMode
(如其中一个答案所示)将防止出现错误。这意味着您现在可以正确初始化bean。关于异步请求,您应该能够在运行时处理缺少的请求范围