I. Static Agent
The proxy object implements the same interface as the target object. eg: //Save user UserDao(save)Direct preservation UserDaoProxy Add transaction processing to the save method IUserDao.java Target Object Implementation Interface public interface IUserDao{ void save(); } UserDao.java Target object public class UserDao{ public void save(){ System.out.println("Saved data") } } ProxyFactory.java Surrogate object public class ProxyFactory implements IUserDao{ //Maintaining a target object private IUserDao target; public ProxyFactory(target){ this.target=target; } } public void save(){ System.out.println("Transaction opening"); target.save(); System.out.println("Transaction closure"); } TestMain.java public class TestMain{ @Test public void test(){ IUserDao target =new UserDao(); IUserDao proxy=new ProxyFactory(target); proxy.save(); } } //Summarize static proxy: 1)It can extend the function of the target object without modifying the function of the target object. 2)Disadvantages: --> Because the proxy object needs the same interface as the target object. So there will be many proxy classes, too many classes. --> Once the interface adds methods, both the target object and the proxy object are maintained.
II. Dynamic Agent
1) Proxy object, no need to implement interface;
2) Proxy object generation is to construct proxy object dynamically in memory by using JDK API (we need to specify the type of interface to create proxy object/target object);
3) Dynamic proxy, JDK proxy, interface proxy;
API for generating proxy objects in JDK:
|– Proxy
static Object newProxyInstance(
ClassLoader loader, specifying that the current target object uses a class loader
Class<? > [] interfaces, the type of interface that the target object implements
Invocation Handler h Event Processor
)
IUserDao. Java UserDao. Java Ibid. // Agent Factory does not need to implement IUserDao public class ProxyFactory{ // Maintaining a target object private Object target; public ProxyFactory(Object target){ this.target=target; } // Generating proxy objects public Object getProxyInstance(){ return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvacationHandler(){ @Override public Object invoke(Object proxy,Method method,Ojbect[] args) throws Throwable{ System.out.println("Open Transaction"); // Executing the Target Object Method Object returnValue=method.invoke(target,args); System.out.println("commit transaction"); return returnValue; } }); } } App.java public class App{ IUserDao target =new UserDao(); IUserDao proxy=new ProxyFactory(target).getProxyInstance(); proxy.save(); } Dynamic Agent Summary: The proxy object does not need to implement the interface, but the target object must implement the interface; otherwise, the dynamic proxy can not be used! (class $Proxy0 implements IuserDao) Reflection: There is a target object, want to expand the function, but the target object does not realize the interface, how to expand the function? Class UserDao{} // Ways of subclassing Class subclass extends UserDao{} Implementing it as a subclass (cglib proxy)
III. cglib Agent
Cglib proxy, also known as subclass proxy. A subclass object is constructed in memory to extend the function of the target object.
JDK's dynamic proxy has a limitation that objects using dynamic proxy must implement one or more interfaces. If you want to proxy classes that do not implement interfaces, you can use CGLIB to implement them.
CGLIB is a powerful and high performance code generation package that can extend Java classes and implement Java interfaces at runtime. It is widely used by many AOP frameworks, such as Spring AOP and dynaop, to provide interception of methods for them.
The bottom layer of CGLIB package is to convert bytecode and generate new classes by using a small and fast bytecode processing framework ASM. Direct use of ASM is discouraged because it requires you to be familiar with the internal structure of JVM, including the format and instruction set of class files.
Cglib Subclass Agents: 1) Need to introduce cglib – jar Documents, however spring The core package is already included cglib Functions, so direct introduction spring-core-3.2.5.jar Yes. 2)With the introduction of functional packages, subclasses can be dynamically constructed in memory 3)A proxy class cannot be final, Otherwise, the error will be reported. 4) If the method of the target object is final/static, Then it will not be intercepted, that is, it will not execute additional business methods on the target object. //In Spring's AOP programming, //If the object added to the container has an implementation interface, it is proxyed by JDK. //If the target object does not implement the interface, Cglib proxy is used. //No IUser Dao is available UserDao Ditto ProxyFactory.java public class ProxyFactory implements MethodInterceptor{ private Object target; public ProxyFactory(Object target){ this.target=target; } // Create proxy objects for target objects public Object getProxyInstance(){ //1. tool class Enhancer en = new Enhancer(); //2. Setting parent class en.setSuperclass(target.getClass()); //3. Setting callback function en.setCallback(this); //4. Create subclasses (proxy objects) return en.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable{ System.out.println("Open transaction"); Object returnValue=method.invoke(target,args); System.out.println("Closing transaction"); return returnValue; } } App.java public class App{ @Test public void test(){ UserDao target=new UserDao(); UserDao proxy=(UserDao)new ProxyFactory(target).getProxyInstance(); proxy.save(); } }