Java dynamic Proxy mechanism (JDK dynamic agent and Cglib Dynamic agent difference) __JDK Dynamic Proxy

Source: Internet
Author: User
Tags rollback throwable

A proxy is a common design pattern designed to provide a proxy for other objects to control access to an object. The proxy class is responsible for preprocessing messages for the delegate class, filtering messages and forwarding messages, and performing subsequent processing of the message after the class is executed. Before we talk about dynamic proxies, let's take a look at what a static proxy is, taking transaction control as an example.

1. Static proxy

1.1 Pom.xml File Configuration

<properties> <!--Spring--> <spring.version>4.1.3.RELEASE</spring.version> </propertie S> <dependencies> <!--Spring Begin--> <dependency> <groupid>org.springframewo Rk</groupid> <artifactId>spring-context</artifactId> <version>${spring.version}&lt
        ;/version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </ dependency> <dependency> <groupId>org.springframework</groupId> <artifactid&gt ;spring-webmvc</artifactid> <version>${spring.version}</version> </dependency> ;d ependency> <groupId>org.springframework</groupId> <artifactid>spring-jdbc</artif Actid> <version>${spring.version}</version> </dependency> <dependency> <groupid>org.sprin Gframework</groupid> <artifactId>spring-aspects</artifactId> <version>${spring.ver sion}</version> </dependency> <dependency> <groupid>org.springframework</groupi
    D> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!--Spring end--> </dependencies>

1.2 Business Interface Code

Public interface UserService {
    /**
     * * 
     feature Description: <br>
     *〈 Save User
     * *
     @since [1.0.0] (optional)
     Public
    void Saveuser ();

    /**
     * * 
     feature Description: <br>
     *〈 Update User
     * *
     @since [1.0.0] (optional)/public
    void UpdateUser ( );
}

1.3 Business Implementation Class code

@Service ("UserService") Public
class Userserviceimpl implements UserService {
    @Override public
    Void Saveuser () {
        System.out.println ("UserService saveuser () ...");
    }

    @Override public
    void UpdateUser () {
        System.out.println ("UserService updateuser () ...");
    }

1.4 Transaction Management Class code

@Service ("TransactionManager") public
class TransactionManager {public
    void BeginTransaction () {
        SYSTEM.OUT.PRINTLN ("Open transaction ...");
    }

    public void Commint () {
        System.out.println ("Commit transaction ...");
    }

    public void rollback () {
        System.out.println ("ROLLBACK TRANSACTION ...");
    }

1.5 proxy class Code

@Service ("Userserviceproxy") Public
class Userserviceproxy implements UserService {
    @Resource (name = " UserService ")
    private userservice userservice;

    @Resource (name = "TransactionManager")
    private TransactionManager TransactionManager;

    @Override public
    void Saveuser () {
        try {
            transactionmanager.begintransaction ();
            Userservice.saveuser ();
            Transactionmanager.commint ();
        } catch (Exception e) {
            transactionmanager.rollback ();
        }
    }

    @Override public
    void UpdateUser () {
        try {
            transactionmanager.begintransaction ();
            Userservice.updateuser ();
            Transactionmanager.commint ();
        } catch (Exception e) {
            transactionmanager.rollback ();}}}

1.6 Test Class Code

@RunWith (Springjunit4classrunner.class)
@ContextConfiguration (locations = {"Classpath:applicationContext.xml "}) public
class Proxytest {
    @Resource (name =" Userserviceproxy ")
    private userservice userservice;

    @Test public
    void Teststaticproxy () {
        userservice.saveuser ();
    }
}

1.7 Test Results

Open a transaction ....
UserService saveuser ()
... Commit TRANSACTION ....

From the above code, you can see the static agent to bring us a series of problems, such as in the proxy object contains a reference to the real object , if we need for different business agents, it is necessary for each business to create a proxy object, is very troublesome, so led to the dynamic agent.

2.JDK Dynamic Proxy

2.1 Business Class Interface

Public interface UserService {
    /**
     * * 
     feature Description: <br>
     *〈 Save User
     * *
     @since [1.0.0] (optional) c19/>*/public
    void Saveuser ();

    /**
     * * 
     feature Description: <br>
     *〈 Update User
     * *
     @since [1.0.0] (optional)/public
    void UpdateUser ();
}

2.2 Business Implementation Class

@Service ("UserService") Public
class Userserviceimpl implements UserService {
    @Override public
    Void Saveuser () {
        System.out.println ("UserService saveuser () ...");
    }

    @Override public
    void UpdateUser () {
        System.out.println ("UserService updateuser () ...");
    }

2.3 Transaction Management Class code

@Service ("TransactionManager") public
class TransactionManager {public
    void BeginTransaction () {
        SYSTEM.OUT.PRINTLN ("Open transaction ...");
    }

    public void Commint () {
        System.out.println ("Commit transaction ...");
    }

    public void rollback () {
        System.out.println ("ROLLBACK TRANSACTION ...");
    }

2.4 Proxy class Code

@Service ("Transactionmanagerproxy") Public
class Transactionmanagerproxy implements Invocationhandler {
    Private Object target;

    @Resource (name = "TransactionManager")
    private TransactionManager TransactionManager;

    The public object Createproxyobject (object) {
        This.target = object;
        Return Proxy.newproxyinstance (This.getclass (). getClassLoader (), Target.getclass (). Getinterfaces (), this);

    public object invoke (object proxy, Method method, object[] args) throws Throwable {
        Transactionmanager.begintransaction ();
        object = null;
        try {
            object = Method.invoke (target, args);
            Transactionmanager.commint ();
        } catch (Exception e) {
            transactionmanager.rollback ();
        }
        return object;
    }

2.5 Test Class Code

@RunWith (Springjunit4classrunner.class)
@ContextConfiguration (locations = {"Classpath:applicationContext.xml '} ' public
class Proxytest {
    @Resource (name = "Transactionmanagerproxy")
    private Transactionmanagerproxy Transactionmanagerproxy;

    @Test public
    void Teststaticproxy () {
        UserService userservice = (userservice) Transactionmanagerproxy.createproxyobject (New Userserviceimpl ());
        Userservice.saveuser ();
    }

2.6 Test Results

Open a transaction ....
UserService saveuser ()
... Commit TRANSACTION ....

However, the dynamic proxy for JDK relies on the interface implementation, and if some classes do not implement the interface, the JDK proxy cannot be used, which requires the use of the Cglib dynamic proxy.

3.CGLIB Dynamic Proxy

3.1 Service Interface Class

Public interface UserService {
    /**
     * * 
     feature Description: <br>
     *〈 Save User
     * *
     @since [1.0.0] (optional)
     Public
    void Saveuser ();

    /**
     * * 
     feature Description: <br>
     *〈 Update User
     * *
     @since [1.0.0] (optional)/public
    void UpdateUser ( );
}

3.2 Business Implementation Class

@Service ("UserService") Public
class Userserviceimpl implements UserService {
    @Override public
    Void Saveuser () {
        System.out.println ("UserService saveuser () ...");
    }

    @Override public
    void UpdateUser () {
        System.out.println ("UserService updateuser () ...");
    }

3.3 Transaction Management class

@Service ("TransactionManager") public
class TransactionManager {public
    void BeginTransaction () {
        SYSTEM.OUT.PRINTLN ("Open transaction ...");
    }

    public void Commint () {
        System.out.println ("Commit transaction ...");
    }

    public void rollback () {
        System.out.println ("ROLLBACK TRANSACTION ...");
    }

3.4 Transaction proxy class

public class Transactionmanagerproxy implements Org.springframework.cglib.proxy.InvocationHandler {private Object tar
    Get

    Private TransactionManager TransactionManager;
        Public Transactionmanagerproxy (Object target, TransactionManager transactionmanager) {this.target = target;
    This.transactionmanager = TransactionManager;
        //Create proxy Object public Object Getproxyinstance () {Enhancer enhancer = new enhancer ();
        Enhancer.setclassloader (This.getclass (). getClassLoader ());
        Enhancer.setsuperclass (Target.getclass ());
        Enhancer.setcallback (this);
    return Enhancer.create (); public object invoke (object proxy, Method method, object[] args) throws Throwable {Transactionmanager.begi
        Ntransaction ();
        object = null;
            try {object = Method.invoke (target, args);
        Transactionmanager.commint ();
 catch (Exception e) {transactionmanager.rollback ();       return object; }
}

3.5 Test class

@RunWith (Springjunit4classrunner.class)
@ContextConfiguration (locations = {"Classpath:applicationContext.xml '} ' public
class Proxytest {
    @Resource (name = "TransactionManager")
    private TransactionManager TransactionManager;

    @Test public
    void Teststaticproxy () {
        Userserviceimpl Userserviceimpl = (userserviceimpl) New Transactionmanagerproxy (New Userserviceimpl (), TransactionManager). Getproxyinstance ();
        Userserviceimpl.saveuser ();
    }

3.6 Test Results

Open a transaction ....
UserService saveuser ()
... Commit TRANSACTION ....

The 1.CGLIB can generate subclasses of the target class and override methods of the parent class other than the final modifier.
2. The requirements of the class can not be final, to intercept the method to be final, not static, not private
3. The smallest unit of a dynamic proxy is a class (methods in all classes are processed)

Note: If the target object implements several interfaces, spring will use the JDK dynamic proxy, and if the target object does not implement any interfaces, spring uses the Cglib library to generate a subclass of the target object.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.