Basic principles of agent mode
Basic introduction to static agent mode
- Proxy mode: provides an avatar for an object to control access to the object. That is, the target object is accessed through the proxy object The advantage of this is that additional function operations can be enhanced on the basis of the realization of the target object, that is, the function of the target object can be extended.
- The proxied object can be a remote object, an object with high creation cost, or an object requiring security control
- The agent mode has different forms, mainly including three kinds of static agent, dynamic agent (JDK agent, interface agent) and Cglib agent (you can dynamically create objects in memory without implementing interfaces, which belongs to the category of dynamic agent)..
Case realization
- Define an interface: ITeacherDao
- The target object TeacherDAO implements the interface ITeacherDAO
- Using the static proxy method, you need to implement ITeacherDAO in the proxy object TeacherDAOProxy
- When called, the target object is called by calling the method of the proxy object
- Special reminder: the proxy object and the target object should implement the same interface, and then call the method of the target object by calling the same method
1. Define an interface
public interface ITeacherDao { void teach(); }
2. Create a concrete class implementation interface
public class TeacherDao implements ITeacherDao{ @Override public void teach() { System.out.println("The teacher is teaching....."); } }
3. Create proxy classes and implement interfaces
public class TeacherProxy implements ITeacherDao{ private ITeacherDao dao; public TeacherProxy(ITeacherDao dao) { this.dao = dao; } @Override public void teach() { System.out.println("Before teaching...."); dao.teach(); System.out.println("After teaching...."); } }
4. Testing
public class Client { public static void main(String[] args) { //Create a proxy interface ITeacherDao dao = new TeacherDao(); //Create a proxy object and aggregate the proxied object TeacherProxy teacherProxy = new TeacherProxy(dao); //Call proxy method teacherProxy.teach(); } }
Advantages and disadvantages of static agent
- Advantages: the target function can be extended through the proxy object without modifying the function of the target object
- Disadvantages: because the proxy object needs to implement the same interface as the target object, there will be many proxy classes. Once methods are added to the interface, both the target object and the proxy object must be maintained
Basic introduction of dynamic agent mode
- The proxy object does not need to implement the interface, but the target object must implement the interface, otherwise the dynamic proxy cannot be used
- The generation of proxy object is to dynamically build proxy object in memory by using JDK API
- Dynamic agent is also called JDK agent and interface agent
Case realization
1. Create a ProxyFactory dynamically instantiated object
public class ProxyFactory { private Object obj; public ProxyFactory(Object obj) { this.obj = obj; } public Object getProxyInstance() { //explain //1. Classloader: Specifies the class loader used by the current target object, and the method to obtain the loader is fixed //2. Class<?> [] interfaces: the interface type implemented by the target object. Use the generic method to confirm the type //3. InvocationHandler h: event processing. When the method of the target object is executed, the event handler method will be triggered and the current execution will be executed //The target object method of is passed in as a parameter return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("jdk The agency started"); //Method of calling target object using reflection mechanism Object returnVal = method.invoke(obj, args); System.out.println("Agent end"); return returnVal; } }); } }
2. Testing
public class Client { public static void main(String[] args) { //Create a proxy interface ITeacherDao dao = new TeacherDao(); ITeacherDao proxy = (ITeacherDao)new ProxyFactory(dao).getProxyInstance(); // proxy=class com. sun. proxy.$ Proxy objects are dynamically generated in proxy0 memory System.out.println(proxy); proxy.teach(); String string = proxy.sayHello("Hello"); System.out.println(string); } }
Introduction to Cglib agent
- Both static proxy and JDK proxy modes require the target object to implement an interface, but sometimes the target object is only a separate object and does not implement any interface. At this time, the target object subclass can be used to implement the proxy - this is Cglib proxy
- Cglib agent is also called subclass agent. It constructs a subclass object in memory to expand the function of the target object. Some books also attribute cglib agent to dynamic agent.
- Cglib is a powerful high performance code generation package, which can extend java classes and implement java interfaces at run time It is widely used by many AOP frameworks, such as Spring AOP, to implement method interception
- How to select proxy mode in AOP programming:
- The target object needs to implement the interface and use JDK proxy
- The target object does not need to implement the interface and uses Cglib proxy
- The bottom layer of Cglib package is to convert bytecode and generate new classes by using bytecode processing framework ASM
Case realization
1. Import jar
2. Write subclass TeacherDao
public class TeacherDao { public void teach() { System.out.println("The teacher is teaching...."); } }
3. Implement the MethodInterceptor interface to proxy subclasses
public class CglibProxy implements MethodInterceptor{ private Object target; public CglibProxy(Object target) { this.target = target; } public Object getProxyInstance() { //Create a tool class Enhancer enhancer = new Enhancer(); //Set parent class enhancer.setSuperclass(this.target.getClass()); //Set callback function enhancer.setCallback(this); //Create a subclass object, the proxy object return enhancer.create(); } @Override public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("Cglib proxy pattern~start"); Object returnVal = method.invoke(target, arg2); System.out.println("Cglib Agent end~end"); return returnVal; } }
3. Testing
public class Client { public static void main(String[] args) { //Create proxied object TeacherDao dao = new TeacherDao(); //Get proxy object TeacherDao daoProxy = (TeacherDao)new CglibProxy(dao).getProxyInstance(); //Call method daoProxy.teach(); } }