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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 04:47:42  来源:igfitidea点击:

proxyMode ScopedProxyMode.TARGET_CLASS vs ScopedProxyMode.INTERFACE

javaspring

提问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 getBeanbean as your PrototypeBeandoesn'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 prototypescoped bean.

在您的情况下,这将导致每次调用getBeanbean 时都会产生一个 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 prototypeeach 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.INTERFACESand proxyMode = ScopedProxyMode.TARGET_CLASSas 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 作为变量类型不会产生任何区别。