Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

proxyMode ScopedProxyMode.TARGET_CLASS vs ScopedProxyMode.INTERFACE

Tags:

java

spring

As other SO answers suggested, use proxy mode type as per your need, I am still confused;

@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

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?

like image 202
Amit Kumar Gupta Avatar asked Oct 09 '16 15:10

Amit Kumar Gupta


People also ask

What is proxyMode ScopedProxyMode Target_class?

Main class Configuring the Scoped Proxy for Prototype bean In above example proxyMode=ScopedProxyMode. TARGET_CLASS causes an AOP proxy to be injected at the target injection point. The default proxyMode is ScopedProxyMode.NO . Another possible value, ScopedProxyMode.

What is proxy mode in spring?

The proxyMode attribute is necessary because at the moment of the instantiation of the web application context, there is no active request. Spring creates a proxy to be injected as a dependency, and instantiates the target bean when it is needed in a request.

What is AOP scoped proxy in spring?

Marker annotation identical in functionality with <aop:scoped-proxy/> tag. Provides a smart proxy backed by a scoped bean, which can be injected into object instances (usually singletons) allowing the same reference to be held while delegating method invocations to the backing, scoped beans.


1 Answers

@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.

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.

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.

like image 137
M. Deinum Avatar answered Sep 17 '22 23:09

M. Deinum