1. Agent mode
The proxy model is called Proxy or Surrogate in English, and both can be translated as "agent" in Chinese. The so-called proxy means that one person or an institution takes action on behalf of another person or another institution. In some cases, a client does not want or cannot directly refer to an object, and the proxy object can act as an intermediary between the client and the target object.
Explain the differences between various agents by simply simulating the execution process of transactions
1.1 Static proxy
Source code is created by programmers or automatically generated by specific tools and then compiled. Before the program runs, the .class file of the proxy class already exists.
public interface PersonDao { void savePerson();} public class PersonDaoImpl implements PersonDao { @Override public void savePerson() { System.out.println("save person"); }} public class Transaction { void beginTransaction(){ System.out.println("begin Transaction"); } void commit(){ System.out.println("commit"); }}Next, write a static proxy class---implement the PersonDao interface
/** * Static proxy class* @author qjc */public class PersonDaoProxy implements PersonDao{ PersonDao personDao; Transaction transaction; public PersonDaoProxy(PersonDao personDao, Transaction transaction) { this.personDao = personDao; this.transaction = transaction; } @Override public void savePerson() { this.transaction.beginTransaction(); this.personDao.savePerson(); this.transaction.commit(); }}test
/** * Test static proxy* @author qjc */public class TestPersonProxy { @Test public void testSave(){ PersonDao personDao = new PersonDaoImpl(); Transaction transaction = new Transaction(); PersonDaoProxy proxy = new PersonDaoProxy(personDao, transaction); proxy.savePerson(); }}Summarize:
1. Static proxy mode does not reuse transactions
2. Suppose there are 100 classes and 100 proxy. How many methods are there in the interface, how many methods must be implemented in the proxy layer, and how many transactions must be opened and submitted as many methods.
3. If a proxy implements multiple interfaces, if one of the interfaces changes (a method is added), then proxy also needs to change accordingly.
1.2 JDK dynamic proxy
Dynamic proxy class: It is created dynamically using reflection mechanism when the program is running.
The dynamic proxy of JDK must meet four conditions: 1. Target interface 2. Target class 3. Interceptor 4. Proxy class
Using the PersonDao interface, PersonDaoImpl class and Transaction class in the previous example
Write an interceptor
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/** * Interceptor* 1. Import target class in * 2. Import things in * 3. Invoke completion: start transactions, call the method of the target object, and commit transaction* * @author qjc */public class Interceptor implements InvocationHandler { private Object target; // target class private Transaction transaction; public Interceptor(Object target, Transaction transaction) { this.target = target; this.transaction = transaction; } /** * @param proxy instance of the proxy class of the target object* @param method Corresponding to the Method instance that calls the interface method on the proxy instance* @param args The object array passed into the method parameter values on the proxy instance* @return The return value of the method, no return value is null * @throws Throwable */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); if ("savePerson".equals(methodName) || "deletePerson".equals(methodName) || "updatePerson".equals(methodName)) { this.transaction.beginTransaction(); // Enable transaction method.invoke(target); // Call the target method this.transaction.commit(); // Submit transaction} else { method.invoke(target); } return null; }}test
/** * Test jdk dynamic proxy* @author qjc */public class TestJDKProxy { @Test public void testSave(){ /** * 1. Create a target object* 2. Create a transaction* 3. Create an interceptor* 4. Dynamically generate a proxy object*/ Object target = new PersonDaoImpl(); Transaction transaction = new Transaction(); Interceptor interceptor = new Interceptor(target, transaction); /** * Parameter 1: Set the class loader used by the code, which generally uses the same class loader as the target class* Parameter 2: Set the interface implemented by the proxy class, and use the same interface as the target class* Parameter 3: Set the callback object. When the method of the proxy object is called, the invoke method of the specified object will be called*/ PersonDao personDao = (PersonDao) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), interceptor); personDao.savePerson(); }}Summarize :
1. Because the proxy class generated by JDKProxy implements the interface, all methods in the target class are included in the proxy class.
2. All methods of the generated proxy class intercept all methods of the target class. The content of the invoke method in the interceptor is exactly the composition of each method of the proxy class.
3. Interfaces must exist when using JDKProxy.
4. The three parameters in the invoke method can access the API of the called method, the parameters of the called method, and the return type of the called method of the target class.
shortcoming:
1. In the interceptor, except for calling the target method of the target object, the function is relatively single. In this example, only transactions can be processed.
2. The if judgment statement of the invoke method in the interceptor is unreliable in a real development environment, because once there are many if statements, it needs to be written.
1.3 CGLIB Dynamic Proxy
Use PersonDaoImpl class and Transaction class in the previous example (no interface)
Write interceptor classes
import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;/** * CGLIB proxy interceptor* @author qjc */public class Interceptor implements MethodInterceptor { private Object target; // proxy target class private Transaction transaction; public Interceptor(Object target, Transaction transaction) { this.target = target; this.transaction = transaction; } /** * Create the proxy object of the target object* * @return */ public Object createProxy() { // Code enhancement Enhancer enhancer = new Enhancer(); // This class is used to generate the proxy object enhancer.setCallback(this); // The parameter is the interceptor enhancer.setSuperclass(target.getClass());// Set the parent class return enhancer.create(); // Create a proxy object} /** * @param obj Instance of the target object proxy class* @param method Method instance that calls the parent class method on the proxy instance* @param args An array of objects passed into the method parameter values on the proxy instance* @param methodProxy Use it to call the method of the parent class* @return * @throws Throwable */ public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { this.transaction.beginTransaction(); method.invoke(target); this.transaction.commit(); return null; }}test
/** * Test cglib dynamic proxy* The proxy object generated through cglib, the proxy class is a subclass of the target class* @author qjc */public class TestCglibProxy { @Test public void testSave(){ Object target = new PersonDaoImpl(); Transaction transaction = new Transaction(); Interceptor interceptor = new Interceptor(target, transaction); PersonDaoImpl personDaoImpl = (PersonDaoImpl) interceptor.createProxy(); personDaoImpl.savePerson(); }}Summarize:
1. CGlib is a powerful, high-performance, and high-quality Code generation class library. It can extend Java classes and implement Java interfaces during runtime.
2. Use CGlib to generate a proxy class as a subclass of the target class.
3. No interface is required to generate proxy classes using CGlib
4. The proxy class generated by CGLib overrides the methods of the parent class.
5. The content of the intercept method in the interceptor is exactly the difference between the method body CGLIB and JDK dynamic proxy in the proxy class:
JDK:
The target class and the proxy class implement a common interface
The interceptor must implement the InvocationHandler interface, and the content of the invoke method body in this interface is the content of the proxy object method body.
CGLIB:
The target class is the parent class of the proxy class
The interceptor must implement the MethodInterceptor interface, and the intercept method in the interface is the method body of the proxy class, and the bytecode enhancement mechanism is used to create the proxy object.
2. Oriented oriented programming
OOP (Object-Oriented Programming): Encapsulation, Inheritance, Polymorphism, Abstraction
Encapsulation, basic and modular management of code. Each class may have its own functions. If something goes wrong, just look for someone to discuss the matter. From the perspective of modification, it may be risky to modify the code directly. This is not a long-term solution. The most natural thing is to change from type encapsulation. However, how to integrate new types and old systems, so it is necessary to establish a blood relationship between classes. Then this is the requirement of inheritance. Through inheritance, you can find that these classes are related and there is a father-son relationship between them. Then, on the basis of inheritance, polymorphisms have decisive characteristics. Therefore, it is generally believed that the most core feature of object-oriented is actually polymorphism. The first few are all laying the groundwork. Polymorphism is its core feature. The rewrite method in the subclass represents the extension of this level, and it can be integrated into the old system and can work normally. This is the reuse of this level, new methods, old systems, extensions and reuse.
AOP (section-oriented programming):
Essential programming is a technology that dynamically adds functions to programs without modifying the source code through precompiled runtime dynamic proxy.
Difference between OOP and AOP:
OOP: Abstract encapsulation is carried out on the entities and their properties and behaviors of the business processing process to obtain a clearer division of logical units.
AOP: Extracts the cross-cutting logic in the business process. It faces a certain step or stage in the process to obtain the low coupling isolation effect between the parts of the logic process. These two design ideas have essential differences in goals. AOP has achieved reuse of code blocks.
spring AOP proxy mechanism:
1. If the target object implements several interfaces, spring uses JDK's java.lang.reflect.Proxy class proxy.
Advantages: Because there is an interface, the system is more loosely coupled
Disadvantages: Create interfaces for each target class
2. If the target object does not implement any interface, spring uses the CGLIB library to generate a subclass of the target object.
Advantages: Because the proxy class and the target class are inherited, there is no need for an interface to exist.
Disadvantages: Because there is no interface used, the coupling of the system is not as good as the dynamic proxy using JDK.
Using the PersonDao interface, PersonDaoImpl class, and Transaction class
Write spring configuration
<bean id="personDao"></bean> <bean id="transaction"></bean> <aop:config> <!-- Pointcut expression determines the target class--> <aop:pointcut expression="execution(* cn.qjc.aop.xml.PersonDaoImpl.*(..))" id="perform"/> <!-- ref points to the object as the section--> <aop:aspect ref="transaction"> <aop:before method="beginTransaction" pointcut-ref="perform"/> <aop:after-returning method="commit" pointcut-ref="perform"/> </aop:aspect> </aop:config> </beans>
test
/** * Test spring dynamic proxy* @author qjc */public class TransactionTest { @Test public void testSave(){ ApplicationContext context = new ClassPathXmlApplicationContext("cn/qjc/aop/xml/applicationContext.xml"); PersonDao personDao = (PersonDao) context.getBean("personDao"); personDao.savePerson(); }}spring AOP principle
1. When the spring container is started, two beans are loaded and instantiated.
2. When the spring container parses the configuration file to <aop:config>, parse the point-cut expression and match the beans of the spring container content according to the point-cut expression.
3. If the match is successful, create a proxy object for the bean
4. When the client uses context.getBean to obtain an object, if the object has a proxy object, it returns the proxy object. If there is no proxy object, it returns the object itself.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.