动态代理(jdk & cglib)

前言

看到代理模式的时候,顺便搜索了下动态代码的两种实现。
这里顺手记录下


一、jdk动态代理

1.接口和实现类

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

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

2.代理类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.测试类


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.输出

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

二、cglib实现

1.引入库

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

2.接口和实现类

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

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.测试类


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.输出结果

cglib before
hello
hello2
cglib after
final method
static method

总结

代理模式中的静态代理,几乎没啥实用价值。
AOP(切面)其底层就是实用的JDK动态代理。

效率比较:cglib动态代理更快

猜你喜欢

转载自blog.csdn.net/qq_37700773/article/details/129795587