Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

A dynamic proxy

Proxy object, which does not need to implement the interface, but the target object must implement the interface, otherwise dynamic proxy cannot be used

Proxy object generation, is the use of JDK API, dynamic in memory to build proxy object

Dynamic proxies are also called JDK proxies, interface proxies

Use the API

Proxy class package: java.lang.reflect.proxy

The JDK implementation proxy only needs to use the newProxyInstance method, but this method takes three arguments, which are written as follows:

static Object newProxyInstance(ClassLoader loader, Class<? >[] interfaces,InvocationHandler h )

getProxyInstance();

Based on the incoming object, the target object, using the return mechanism, returns a proxy object, and then through the proxy object, calls the target object method

So let’s write the interface first

Public interface ITeacherDao {void teach(); Void sayHello(String name); }Copy the code

Then write the implementation class of the interface

public class TeacherDao implements ITeacherDao { @Override public void teach() { // TODO Auto-generated method stub System.out.println(" teacher teaching.... "); } @Override public void sayHello(String name) { // TODO Auto-generated method stub System.out.println("hello " + name); }}Copy the code

Here is our proxy class

Public abstract class ProxyFactory {// Maintain a target Object, Object private Object target; Public ProxyFactory(Object target) {this.target = target; } public Object getProxyInstance() {* * public static Object newProxyInstance(ClassLoader) loader, Class<? >[] interfaces, InvocationHandler h) //1. >[] interfaces: the type of the interface implemented by the target object, using generic methods to confirm the type //3. Transaction processing, executing a method on a target object, */ return proxy.newProxyInstance (target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method Method, Object[] args) throws Throwable {// TODO auto-generated Method stub system.out.println ("JDK proxy start ~~"); Object returnVal = method.invoke(target, args); System.out.println("JDK proxy submission "); return returnVal; }}); }}Copy the code

Finally, the calling class

public class Client extends TeacherDao { public static void main(String[] args) { // TODO Auto-generated method stub ITeacherDao Target = new TeacherDao(); ITeacherDao proxyInstance = (ITeacherDao) New ProxyFactory(target).getProxyInstance(); // proxyInstance=class com.sun.proxy.$Proxy0 // proxyInstance=class com.sun.proxy proxyInstance.getClass()); // Proxyinstance.teach (); proxyInstance.sayHello(" tom "); }}Copy the code

Additional agent

Both static proxies and JDK proxies require the target object to implement an interface, but sometimes the target object is a single object that does not implement any interface. In this case, the target object subclass can be used to implement the proxy – this is the Cglib proxy

The Cglib proxy, also known as a subclass proxy, builds a subclass object in memory to extend the power of the target object. Some books also attribute the Cglib proxy to a dynamic proxy.

Cglib is a powerful, high-performance code generation package that extends Java classes and implements Java interfaces at run time. It is widely used by many AOP frameworks, such as Spring AOP, to implement method interception

How to choose proxy patterns in AOP programming:

  • The target object needs to implement the interface, using JDK proxies
  • The target object does not need to implement the interface and uses the Cglib proxy

At the bottom of the Cglib package is the use of the bytecode processing framework ASM to transform bytecode and generate new classes

Cglib proxy mode implementation steps

  1. The JAR file for Cglib needs to be imported

  2. In memory dynamically build subclasses, pay attention to the class not as final agent, otherwise an error Java. Lang. IllegalArgumentException:

  3. If the methods of the target object are final/static, they are not intercepted, that is, no additional business methods of the target object are executed.

There were no interfaces, so we started with TeacherDao

Public class TeacherDao {public String teach() {system.out.println (" cglib "); return "hello"; }}Copy the code

Here is our proxy class

Public class ProxyFactory implements MethodInterceptor {private Object target; Public ProxyFactory(Object Target) {this.target = target; } public Object getProxyInstance() {//1. Create a utility class Enhancer Enhancer = new Enhancer(); SetSuperclass (target.getClass())); //3. Set the callback function enhancer.setCallback(this); Return enhancer. Create (); } // Override the intercept method, @override public Object Intercept (Object arg0, Method Method, Object[] args, MethodProxy arg3) throws Throwable {// TODO auto-generated method stub system.out.println ("Cglib proxy mode ~~ start "); Object returnVal = method.invoke(target, args); System.out.println("Cglib proxy mode ~~ commit "); return returnVal; }}Copy the code

Finally, we call the class

public class Client extends TeacherDao { public static void main(String[] args) { // TODO Auto-generated method stub TeacherDao Target = new TeacherDao(); TeacherDao proxyInstance = (TeacherDao)new ProxyFactory(target).getProxyInstance(); String res = proxyinstance.teach (); System.out.println("res=" + res); }}Copy the code

Several common agents

Firewall agent

The Intranet penetrates the firewall through proxies to access the public network.

The caching proxy

For example: when requesting resources such as image files, first go to the cache proxy to obtain the resources, if the resources are ok, if not, then go to the public network or database to obtain the resources, then cache.

Remote agent

A local representation of a remote object through which it can be called as if it were a local object. Remote agents communicate information to real remote objects over the network.

Synchronous agent

Mainly used in multi-threaded programming, complete multi-threaded synchronization work