【问题标题】:Spring bean scope as the class of the bean its autowiredSpring bean 范围作为其自动装配的 bean 的类
【发布时间】:2013-06-25 12:48:13
【问题描述】:

我有一个叫做Executor的spring bean我需要这个执行器被注入到两个类中,一个是会话范围的,另一个是单例的,所以我使用@Autowired注解在两个类中注入它,它工作得很好,但是对于会话 bean,执行器只是所有会话的一个,我知道它应该是这样工作的。

我怎样才能让 executor 获得注入的 bean 的范围?现在我所能做的就是为每个类使用两个不同的类。

而且我无法真正理解在中设置属性scoped-proxy 的效果 <context-component-scan />targetClass

编辑

这是我对原型范围的尝试:

假设这是我的会话 soped bean

    @Component
    @Scope("session")
    public class WebExecutor(){

       @Autowired
       private ExecutorService executor;

       @Async
       public void startCalc(){
          executor.start("now");
       }

   }

这是我的 ExecutorService 类

@Component
@Scope("prototype")
public class ExecutorService{

    private int progress;

    public void start(String when){
       //do some stuff and increment the progress
    }

    //getter and setter for progress
}

我还有另一个具有默认单例范围的组件,它也自动装配执行器,因此执行器不能是会话范围。

所以现在我有一个类需要拥有它正在自动装配的 bean 的范围,所以我尝试了原型范围。

这在 Web 版本中应该如何工作是这样的

  1. 您单击一个链接开始执行调用WebExecutor 的方法start
  2. 然后我使用 WebParser 从 ExecutorService 获取进度并将其传回给用户以报告进度。

这在原型之前运行良好,但 ExecutorService 是所有会话之一,

所以我使用原型,但现在进度始终为 0,当我调试 Executor 时,我发现它正在递增,但显然 WebExecutor 看不到递增。

【问题讨论】:

    标签: spring spring-mvc scope javabeans


    【解决方案1】:

    你可以使用prototype 范围。然后它会在构造 Bean 时注入 Executor 的新实例。所以Executor 在创建 bean 时就开始了它的生命周期。

    scoped-proxy=target-class 在你的 bean 周围创建 CGLIB 包装器。所以其他 bean 只持有对这个包装器的引用,并且具有正确范围的正确 bean 被动态注入到这个包装器中。

    即您的session scoped bean 中没有保存很旧的过期request scoped bean,可能是在创建会话时注入的。相反,每次创建新请求时都会注入当前请求的新 bean。通过这种方式,您可以从寿命较长的 bean 中访问寿命较短的 bean,即您的 request scoped bean 来自您的 session scoped bean。

    【讨论】:

    • 很好的答案现在将测试并提供反馈感谢 Ondrej
    • 我对此感到厌烦,但在实例化后,我无法访问会话范围 bean 中的执行程序成员。我所做的是请求调用执行器异步方法,然后在执行后从中获取值,但它不适用于原型
    • 你从不同的session scoped bean 中调用它?如果是这样,那么它可能应该有session scope。您希望您的异步调用及其结果可用多长时间?一节课?你不应该从singletons 访问你的session scoped bean。您应该反之亦然 - 从session beans 访问您的singletons
    • 这正是我正在做的事情,但是会话 bean 中的数据不可用,尽管当我调试执行程序时数据应该是可用的,是的,我希望它可以用于一个session 及其结果只是一些在它工作时发生变化的值,我将它作为局部变量保存到 executor 但是当在 Session Soped bean 中时它是 null
    • 您确定您是从同一个Session 访问Executor 吗?如果你想在不同的会话中分享你的Executor,你应该把它设为application scoped
    猜你喜欢
    • 2013-01-29
    • 2012-11-13
    • 2018-12-24
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 1970-01-01
    • 2013-07-10
    相关资源
    最近更新 更多