正如其他SO答案建议的那样,根据您的需要使用代理模式类型,我仍然感到困惑;
@Configuration
@ComponentScan
public class Application
{
public static void main( String[] args )
{
ApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
PrototypeBeanFactory factoryBean = context.getBean(PrototypeBeanFactory.class);
System.out.println("Let's start");
SomeInterface b1 = factoryBean.getPrototypeBeanInstance();
SomeInterface b2 = factoryBean.getPrototypeBeanInstance();
System.out.println(b1.hashCode());
System.out.println(b2.hashCode());
b1.sayHello();
b2.sayHello();
b1.sayHello();
b2.sayHello();
}
}
@Component
public class PrototypeBeanFactory {
@Lookup
public PrototypeBean getPrototypeBeanInstance(){
System.out.println("It'll be ignored");
return null;
}
}
@Component
@Scope(value="prototype", proxyMode = ScopedProxyMode.INTERFACES)
public class PrototypeBean {
public PrototypeBean() {
System.out.println("I am created");
}
public void sayHello() {
System.out.println("Hello from " + this.hashCode());
}
}
输出
Let's start
I am created
I am created
1849201180
1691875296
Hello from 1849201180
Hello from 1691875296
Hello from 1849201180
Hello from 1691875296
现在,如果我将代理模式更改为TARGET_CLASS
输出
Let's start
-721204056
-721204056
I am created
Hello from 172032696
I am created
Hello from 299644693
I am created
Hello from 1771243284
I am created
Hello from 2052256418
为什么,在基于类的代理的情况下,它会在每个方法调用上创建不同的对象?
答案 0 :(得分:7)
@Component
@Scope(value="prototype", proxyMode = ScopedProxyMode.INTERFACES)
public class PrototypeBean { ... }
在您的情况下,这将导致每次调用getBean
bean时都会导致bean,因为PrototypeBean
没有实现接口,因此无法创建范围内的代理。在您的情况下,您调用查找方法两次,因此您将获得2个实例。这实际上是prototype
范围内的bean的正常行为。
Component
@Scope(value="prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class PrototypeBean { ... }
这将导致创建代理。该代理创建一次,并将在每次调用getBean
时返回。只要在代理上调用方法,它就会根据范围创建新方法或重用现有方法。由于您已将范围指定为prototype
,因此每个方法调用都将导致一个新对象。
注意:如果您的类会实现一个公开适当方法的接口,那么proxyMode = ScopedProxyMode.INTERFACES
和proxyMode = ScopedProxyMode.TARGET_CLASS
的行为就没有区别,因为在这两种情况下将创建范围代理。
答案 1 :(得分:0)
我用sayHello创建了一个PrototypeBeanI接口,并使用了main()中的接口,结果仍然不同。似乎使用PrototypeBeanI或PrototypeBean作为变量类型不会产生任何差异。