【问题标题】:Bean marked with prototype scope not working in Spring标有原型范围的 Bean 在 Spring 中不起作用
【发布时间】:2012-11-27 23:10:51
【问题描述】:

我有两个 bean,Parent 和 Child。我已将子 bean 声明为原型范围。
我希望新的子对象用于调用父类中的任何子方法。例如。在下面的示例中,我希望语句 1 在不同的子对象上调用方法 sayHi,而语句 2 在不同的子对象上调用 sayHi1

一种方法是实现 ApplicationContextAware 并在调用任何子方法之前使用context.getBean("") 获取新的子对象。但我不想那样做。

还有其他选择吗?

@Component
public class Parent{

    @Autowired
    Child child;

    public void sayHello(){     
        child.sayHi();           -------------- (1)
    }

    public void sayHello1(){    
        child.sayHi1();          --------------- (2)
    }
}

@Component
@Scope(value=BeanDefinition.SCOPE_PROTOTYPE)
public class Child{

    public void sayHi(){
        System.out.println("Hi Spring 3.0");

    }

    public void sayHi1(){
        System.out.println("Hi1 Spring 3.0 ");      
    }

}

【问题讨论】:

标签: java spring scope prototype-scope


【解决方案1】:

其他人已经给出了答案,我将包含一个可能有帮助的理论

为了将组件转化为原型,我们这样做 - 你可能已经知道了 :)

@Scope(value=BeanDefinition.SCOPE_PROTOTYPE)
Class B{ .....}

这只有在 B 类被称为.getBean(B.class) 自动装配它也是一个原型时才有帮助。


现在,假设我们这样做

 @Component
    Class A{
   
          @Autowired
          Class B;
     }
   

A 类是单例,它也假定 B 类的每个实例都是单例:|


现在,如何告诉 A 类 B 是 Prototype?

简单,只需包含proxyMode=ScopedProxyMode.TARGET_CLASS,A 类就会知道 B 类是原型!

如下所示:

@Component
@Scope(value=BeanDefinition.SCOPE_PROTOTYPE, proxyMode=ScopedProxyMode.TARGET_CLASS)
public class B{.....}

【讨论】:

    【解决方案2】:

    原型范围意味着 Spring 会在您每次请求时为您提供一个新的 Child 对象(通过注入或从应用程序上下文中显式检索 bean)。在您的Parent 课程中,您只要求了一次Child,因此您只得到了一个。如果你想在你的Parent 中有两个不同的Child 对象,那么自动连接两个:

    @Component
    public class Parent{
    
        @Autowired
        Child child;
    
        @Autowired
        Child child1;
    
        public void sayHello(){     
            child.sayHi();
        }
    
        public void sayHello1(){    
            child1.sayHi1();
        }
    }
    

    【讨论】:

      【解决方案3】:

      修复只是将原型 bean 标记为范围代理,这意味着当您将较小范围的 bean 注入较大范围时(例如在您将原型注入单例的情况下)然后 bean 的代理将被注入到更大的作用域中,当通过代理调用 bean 的方法时,代理理解作用域并做出适当的响应。

      @Component
      @Scope(value=BeanDefinition.SCOPE_PROTOTYPE, proxyMode=ScopedProxyMode.TARGET_CLASS)
      public class Child{
      

      这是reference

      另一种选择可能是使用here 中描述的称为查找方法注入的东西

      【讨论】:

        【解决方案4】:

        你做不到。 ApplicationContext 启动后,只会将一个 bean 注入到 child。 将为每个父母创建一个新的孩子。

        事情是父母只有一个孩子,所以你的 2 个方法将只调用那个孩子的方法。

        您到底想达到什么目的? 我确信有一个合适的解决方案。

        【讨论】:

          【解决方案5】:

          我认为您必须每次都自己创建一个new Child,或者确实使用 spring 上下文来获取新鲜的 bean。

          Spring 只会在需要注入某些东西时(在原型的情况下)创建一个新实例。当你在课堂上时,你实际上已经超出了 spring 的范围。

          这是一个类似的帖子:@Scope("prototype") bean scope not creating new bean

          http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch04s04.html#beans-factory-scopes-prototype 4.4.2 和 4.4.3 部分是相关的。

          【讨论】:

            猜你喜欢
            • 2011-05-06
            • 2013-06-14
            • 1970-01-01
            • 2011-07-13
            • 1970-01-01
            • 1970-01-01
            • 2013-04-19
            • 2012-04-12
            • 2013-01-29
            相关资源
            最近更新 更多