java proxyMode ScopedProxyMode.TARGET_CLASS 与 ScopedProxyMode.INTERFACE
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39945163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
proxyMode ScopedProxyMode.TARGET_CLASS vs ScopedProxyMode.INTERFACE
提问by Amit Kumar Gupta
As other SO answers suggested, use proxy mode type as per your need, I am still confused;
正如其他 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());
}
}
Output
输出
Let's start
I am created
I am created
1849201180
1691875296
Hello from 1849201180
Hello from 1691875296
Hello from 1849201180
Hello from 1691875296
Now if I change the proxy-mode to TARGET_CLASS
现在,如果我将代理模式更改为 TARGET_CLASS
Output
输出
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
Why, in case of class based proxy, it creates different object on each method invocation?
为什么在基于类的代理的情况下,它会在每个方法调用上创建不同的对象?
回答by M. Deinum
@Component
@Scope(value="prototype", proxyMode = ScopedProxyMode.INTERFACES)
public class PrototypeBean { ... }
This, in your case, will lead to a bean per invocation of getBean
bean as your PrototypeBean
doesn't implement an interface and as such a scoped proxy cannot be created. In your case you call the lookup method twice and hence you will get 2 instances. This is actually the normal behavior of a prototype
scoped bean.
在您的情况下,这将导致每次调用getBean
bean 时都会产生一个 bean,因为您PrototypeBean
没有实现接口,因此无法创建作用域代理。在您的情况下,您两次调用查找方法,因此您将获得 2 个实例。这实际上是prototype
作用域 bean的正常行为。
Component
@Scope(value="prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class PrototypeBean { ... }
This will lead to the creation of a proxy. That proxy is created once and will be returned for each call to getBean
. As soon as you invoke a method on the proxy it will, based on the scope, either create a new one or reuse an existing one. As you have specified the scope as prototype
each method invocation will lead to a new object.
这将导致创建代理。该代理创建一次,每次调用getBean
. 一旦您调用代理上的方法,它就会根据作用域创建一个新方法或重用现有方法。由于您已指定范围,因为prototype
每个方法调用都将导致一个新对象。
Note:If your class would implement an interface which exposes the appropriate method, there would be no difference in the behavior of proxyMode = ScopedProxyMode.INTERFACES
and proxyMode = ScopedProxyMode.TARGET_CLASS
as in both cases a scoped proxy would be created.
注意:如果您的类将实现一个公开适当方法的接口,则proxyMode = ScopedProxyMode.INTERFACES
和的行为将没有区别,proxyMode = ScopedProxyMode.TARGET_CLASS
因为在这两种情况下都会创建范围代理。
回答by gli00001
I created an interface PrototypeBeanI with sayHello and used the interface in the main(), still different results. seems that using PrototypeBeanI or PrototypeBean as the variable type does not create any difference.
我用sayHello创建了一个接口PrototypeBeanI,并在main()中使用了该接口,结果还是不同。似乎使用 PrototypeBeanI 或 PrototypeBean 作为变量类型不会产生任何区别。