Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

Dynamic agent

Uncle Huo 2021-01-14 21:25:35 阅读数:2 评论数:0 点赞数:0 收藏数:0

Link to the original text http://zhhll.icu/2020/11/12/java%E5%9F%BA%E7%A1%80/%E5%8F%8D%E5%B0%84/%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/

A dynamic proxy

There are many ways of dynamic proxy , Such as jdk agent ,cglib,ASM etc.

Before we talk about dynamic agents, let's talk about static agents

Static proxy

Static agents are used , You need to define an interface or parent class , The proxy object and the proxy object implement the same interface or inherit the same parent class together

Static proxies use composition patterns , The proxy class contains the objects of the proxy class

public class TestStaticProxy {
public static void main(String[] args) {
NikeClothFactory nikeClothFactory = new NikeClothFactory();
ProxyFactory proxyFactory = new ProxyFactory(nikeClothFactory);
proxyFactory.productCloth();
}
}
// Interface
interface ClothFactory{
void productCloth();
}
// Surrogate class
class NikeClothFactory implements ClothFactory{
@Override
public void productCloth() {
System.out.println("Nike The factory produced one Nike");
}
}
// proxy class
class ProxyFactory implements ClothFactory{
private ClothFactory clothFactory;
public ProxyFactory(ClothFactory clothFactory){
this.clothFactory = clothFactory;
}
@Override
public void productCloth() {
System.out.println(" The agent class starts executing , Ready to call the proxied class ");
clothFactory.productCloth();
}
}

Although static proxy can extend the target function without modifying the function of the target object , But once the interface adds methods , Both the target object and the proxy class need to be modified at the same time , And the proxy object and the proxy object should implement the same interface , As a result, there are many proxy classes , Not easy to maintain

jdk A dynamic proxy

jdk The bottom layer of dynamic proxy is to use java Reflection of , however jdk The premise of a proxy is that the target class must implement the interface

Use steps

  • First, implement a InvocationHandler, Method calls will be forwarded to the class invoke() Method
  • Get the proxy object through dynamic proxy when calling

The core method is Proxy.newProxyInstance(ClassLoader,Class[],InvocationHandler)

Three parameters are respectively expressed

  • ClassLoader The class loader used by the current target object
  • Class[] The type of interface the target object implements
  • InvocationHandler Event handling , When executing the method of the target object , Methods that trigger event handlers , The method of the current execution target object is passed in as a parameter
public class TestDynamicProxy {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
MyInvationHandler myInvationHandler = new MyInvationHandler();
Object obj = myInvationHandler.blind(realSubject);
Subject sub = (Subject) obj;
sub.action();
}
}
// Interface
interface Subject{
void action();
}
// The real way to do it , Surrogate class
class RealSubject implements Subject{
@Override
public void action() {
System.out.println(" The proxy class starts executing ");
}
}
class MyInvationHandler implements InvocationHandler{
// Implements the declaration of the object of the interface's proxy class
Object obj;
// An instance of the proxied class
// Returns an object of a proxy class
public Object blind(Object obj){
this.obj = obj;
// ① Use the class loader of the proxied class ② Interface of the proxied class ③ An instance of the proxy class
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
}
/**
* When an object through a proxy class is called by an overridden method , Will be converted to right invoke Method call
* @param proxy Returning proxy object , In general , stay invoke The object is not used in the method
* @param method The method being called
* @param args When calling a method , Incoming parameter
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(obj,args);
}
}

cglib agent

Static agents and jdk Dynamic proxy must implement interface for target object , But sometimes the target object is just a single object , No interfaces are implemented , At this time, the proxy is implemented in the way of target object subclass , This method is called cglib agent

Cglib The bottom layer of the package is through the use of a bytecode processing framework ASM To transform the bytecode and generate a new class , Because you want to generate subclasses , So the class to be represented cannot be final modification

Need to introduce cglib My bag

<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>

Use steps

  • First realize MethodIntercepor, Method calls are forwarded to intercept() Method
  • Use CGLIB To get the proxy object
public class CglibProxy implements MethodInterceptor {
public Object getProxy(Class clazz){
Enhancer enhancer = new Enhancer();
// Specifies the parent of the proxy class
enhancer.setSuperclass(clazz);
// Set up Callback object
enhancer.setCallback(this);
// Create subclass instances dynamically by bytecode technology
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println(" Preprocessing ");
// call MethodProxy.invokeSuper Method forwards the call to the original object
Object result = methodProxy.invokeSuper(o,objects);
System.out.println(" Post processing ");
return result;
}
}
public class Test {
public void print(){
System.out.println(" Method execution ");
}
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
Test proxyImp = (Test) proxy.getProxy(Test.class);
proxyImp.print();
}
}

Due to its own blog Baidu did not include , Blog address http://zhhll.icu

Copyright statement
In this paper,the author:[Uncle Huo],Reprint please bring the original link, thank you