在Spring中,标记为原型作用域的Bean无法工作。
在Spring中,标记为原型作用域的Bean无法工作。
我有两个bean,Parent和Child。我已将Child bean声明为原型作用域。
我希望使用新的Child对象来调用Parent类中的任何Child方法。例如,在下面的例子中,我希望语句1调用不同的Child对象上的sayHi方法,语句2调用不同的Child对象上的sayHi1方法。
一种方法是实现ApplicationContextAware,并在调用任何Child方法之前使用context.getBean("")获取新的Child对象。但是我不想这样做。
还有其他替代方法吗?
@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 ");
}
}
在Spring中,如果一个bean被标记为prototype作用域,它会在每次请求时创建一个新的实例。然而,有时候在使用prototype作用域的bean时会遇到问题。下面是一个关于这个问题的原因和解决方法的整理。
首先,我们需要将一个组件标记为prototype作用域。这可以通过在类上添加注解@Scope(value=BeanDefinition.SCOPE_PROTOTYPE)
来实现。这样做只有在通过.getBean(B.class)
方法获取B类的实例时才有效,或者在自动装配B类的地方也使用了prototype作用域。
然而,如果我们有这样的代码:
Class A{ Class B; }
其中A类是单例的,并且默认情况下会将B类的所有实例都视为单例。这就是问题所在。
那么,怎样告诉A类将B类视为prototype作用域呢?很简单,只需要在B类的注解中添加proxyMode=ScopedProxyMode.TARGET_CLASS
,A类就会知道B类是prototype作用域的了!具体的代码如下:
(value=BeanDefinition.SCOPE_PROTOTYPE, proxyMode=ScopedProxyMode.TARGET_CLASS) public class B{.....}
通过以上的整理,我们可以清楚地了解到在Spring中使用prototype作用域的bean时遇到问题的原因以及解决方法。
在Spring中,原型作用域的bean在某些情况下可能无法正常工作。解决这个问题的方法是将原型作用域的bean标记为作用域代理。这意味着,当将较小作用域的bean注入到较大作用域中时(比如,在单例作用域中注入原型作用域的bean),会将bean的代理注入到较大作用域中,当通过代理调用bean的方法时,代理会理解作用域并做出适当的响应。
解决方法之一是将原型作用域的bean标记为作用域代理,示例如下:
(value=BeanDefinition.SCOPE_PROTOTYPE, proxyMode=ScopedProxyMode.TARGET_CLASS) public class Child{ //... }
可以参考Spring文档中的这里获取更多信息。
另一种解决方法是使用称为查找方法注入(lookup method injection)的技术,可以在这里了解更多信息。
在Spring中,如果你想要使用原型(prototype)作用域的Bean,你需要自己每次创建一个新的实例,或者使用Spring容器去获取一个新的Bean实例。
Spring只会在需要注入某个属性时创建一个新实例(对于原型作用域的Bean)。当你在一个类中时,你实际上是超出了Spring的范围。
根据stackoverflow上的一个类似问题,你可以参考这篇文章:("prototype") bean scope not creating new bean
你还可以参考Spring官方文档中的相关部分:http://static.springsource.org/spring/docs/3.0.0.M3/reference/html/ch04s04.html#beans-factory-scopes-prototype,其中的4.4.2和4.4.3节对此问题也是相关的。