Dynamic proxy (jdk & cglib)

Preface

When I saw the proxy mode, I searched for two implementations of dynamic code.
Just record it here


1. jdk dynamic proxy

1.Interface and implementation class

public interface Service {
    
    
    void reduceStock();
}
public class ServiceImpl implements Service {
    
    

    @Override
    public void reduceStock() {
    
    
        System.out.println("实现类中...输出");
    }
}

2.Proxy class proxy

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class DynamicProxy implements InvocationHandler {
    
    

    private final Object object;

    public DynamicProxy(Object object) {
    
    
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
        System.out.println("日志开始");
        Object invoke = method.invoke(object, args);
        System.out.println("日志结束");
        return invoke;
    }
}

3.Test class


import java.lang.reflect.Proxy;

public class JdkProxyDemo {
    
    
    public static void main(String[] args) {
    
    
        //实现了接口的业务类
        ServiceImpl iService = new ServiceImpl();
        //获取Class对象
        Class<?> iServiceClass = iService.getClass();
        //代理类 实现需要实现InvocationHandler接口,重写invoke方法 传入业务实现类对象
        DynamicProxy dynamicproxy = new DynamicProxy(iService);

        //创建代理类对象
        Service so = (Service) Proxy.newProxyInstance(iServiceClass.getClassLoader(), iServiceClass.getInterfaces(), dynamicproxy);
        so.reduceStock();
    }
}

4.Output

日志开始
实现类中...输出
日志结束

2. cglib implementation

1. Import the library

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

2.Interface and implementation class

public interface UserService {
    
    
 
    public void say();
 
    public void say2();
 
}
public class UserServiceImpl implements UserService{
    
    
 
    @Override
    public void say() {
    
    
        System.out.println("hello");
        say2();
    }
 
    @Override
    public void say2() {
    
    
        System.out.println("hello2");
    }
 
    public final void finalMethod() {
    
    
        System.out.println("final method");
    }
 
    public static void staticMethod() {
    
    
        System.out.println("static method");
    }
}

3.Proxy class proxy

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class MyInterceptor implements MethodInterceptor {
    
    
 
    private Object target;
 
    public MyInterceptor(Object target) {
    
    
        this.target = target;
    }
 
    /**
     *
     * @param o 代理对象
     * @param method 被代理对象的方法
     * @param objects 方法入参
     * @param methodProxy 代理方法
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    
    
        System.out.println("cglib before");
        // 调用代理类FastClass对象
//        Object result =  methodProxy.invokeSuper(o, objects);
        Object result = methodProxy.invoke(target, objects);
        System.out.println("cglib after");
        return result;
    }
 
}

4.Test class


import net.sf.cglib.proxy.Enhancer;

public class CglibDemo {
    
    
 
    public static void main(String[] args) {
    
    
        UserServiceImpl target = new UserServiceImpl();
 
        // 代理类class文件存入本地磁盘方便我们反编译查看源码
//        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "./code");
        // 通过CGLIB动态代理获取代理对象的过程
        Enhancer enhancer = new Enhancer();
        // 设置enhancer对象的父类
        enhancer.setSuperclass(UserServiceImpl.class);
        // 设置enhancer的回调对象
        enhancer.setCallback(new MyInterceptor(target));
        // 创建代理对象
        UserServiceImpl userService = (UserServiceImpl)enhancer.create();
        // 通过代理对象调用目标方法
        userService.say();
        userService.finalMethod();
        UserServiceImpl.staticMethod();
    }
 
}

5. Output results

cglib before
hello
hello2
cglib after
final method
static method

Summarize

The static proxy in the proxy mode has almost no practical value.
The bottom layer of AOP (aspect) is a practical JDK dynamic proxy.

Efficiency comparison:cglib动态代理更快

Guess you like

Origin blog.csdn.net/qq_37700773/article/details/129795587