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(); } }