Spring proxy mocking (I)

public interface IUserDAO {
    @Transactional
    String add();
    String query();
}

   

public class UserDAOImpl implements IUserDAO {

    public String add() {
        System.out.println("add ok!");
        return "add";
    }
    public String query() {
        System.out.println("query ok!");
        return "query";
    }
}

 

import org.junit.Test;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Spring transaction proxy can be divided into JDK dynamic proxy and CGLIB proxy mode,
 * JDK dynamic proxy is interface dependent,
 * The java.lang.reflect.Proxy.newProxyInstance method dynamically constructs a proxy class instance according to the incoming interface type (obj.getClass.getInterfaces()) and returns,
 * This also explains why the dynamic proxy implementation requires that the object it proxies must implement an interface.
 * This proxy class instance is dynamically constructed in memory, and it implements all the interfaces contained in the incoming interface list.
 *
 *
 * It is to load all beans that need transaction management through such a dynamic proxy, and determine the name of the currently called method in the invoke method according to the configuration.
 * And add appropriate transaction management code before and after the method.invoke method, thus realizing Spring-style transaction management.
 * The AOP implementation in Spring is more complex and flexible, but the basic principles are the same
 * Created by kenny.dong on 2018/4/6.
 */
public class JDKProxyTest {
    @Test
    /**
     * jdk dynamic proxy test
     */
    public void jdkProxyTest(){
        //01. First create the outgoing interface implementation class
        final IUserDAO dao=new UserDAOImpl();
        //02. Class Proxy
        IUserDAO proxy=(IUserDAO) Proxy.newProxyInstance(dao.getClass().getClassLoader(), //Get the class loader of the implementation class
                dao.getClass().getInterfaces(), // Get the implementation class interface
                new InvocationHandler() { //Invocation (call) Handler (processing)
                            /**proxy the proxy object itself
                             * method The proxy object method add()
                             * args add method parameters
                             */
                            public Object invoke(Object proxy, Method method, Object[] args)
                                    throws Throwable {
                                if(method.getAnnotation(Transactional.class) != null){
                                    System.out.println("start Transaction");
                                    //code 1
                                    //real business
                                    //Execute the add method of the dao object, the args parameter is passed in, and the return value is result
                                    Object result = method.invoke(dao, args);
                                    //code 2
                                    System.out.println("commit Transaction");
                                    return result;
                                }else{
                                    return method.invoke(dao, args);
                                }
                            }
          });
        String add = proxy.add();
        System.out.println("add method result" + add);//"add"
        proxy.query();
    }

}

 

 

 

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326128417&siteId=291194637