JAVA动态代理cglib或jdk

cglib或jdk动态代理

Proxy代理,只把tostrng,equal,hashcode交给handler(原对象)去实现,其他的自己实现,所以调用getclass().getName()时返回$proxy0
java.lang.reflect.Proxy代理的原理,1.生成代理类。2.如果原对象设置了需要代理(如autowire注解),则返回代理对象(即添加了增强方法的代理对象),返回的对象想要强转,只能强转成接口
Spring AOP的底层就是通过JDK动态代理或CGLib动态代理技术 为目标Bean执行横向织入。
1.若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理。
2.若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类。
cglib不但可以接受接口,还能接受普通类。

package platformc.aoptest;

import lombok.Data;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;

/**
 * @author: CHX
 * @date: 2021/3/28 20:42
 */
@Data
public class TestFactory implements MethodInterceptor {
    private Object target;
    private MyAdvice advice = new MyAdvice();

    public static void main(String[] args) {
        try {
            //通过代理获取对象
            Object bean = new TestFactory().getBean("platformc.aoptest.TestFactory",
                    "java.util.ArrayList");
            System.out.println(bean.getClass().getName());
            System.out.println(((ArrayList<Object>) bean).size());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过代理获取对象
     *
     * @param proxyName  代理对象类名
     * @param targetName 被代理对象类名
     * @return
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public Object getBean(String proxyName, String targetName) throws ClassNotFoundException,
            IllegalAccessException, InstantiationException {
        //获取代理对象(实际应用中,可更换为判断注解)
        Class<?> aClass = Class.forName(proxyName);
        Object bean = aClass.newInstance();
        if (bean instanceof TestFactory) {
            //如果代理类是我们自定义的代理类,则开始进行方法增强。
            target = Class.forName(targetName).newInstance();
            //设置被代理对象
            ((TestFactory) bean).setTarget(target);
            return ((TestFactory) bean).getProxy();
        }
        return bean;
    }

    /**
     * 分为cglib代理或jdk代理。
     *
     * @return
     */
    public Object getProxy() {
        Object o;
        //分为cglib代理和jdk代理,本身是接口则用jdk,否则用cglib
        if (target.getClass().isInterface()) {
            o = Proxy.newProxyInstance(target.getClass().getClassLoader(),
                    //注意此处,传入是实现的接口。
                    target.getClass().getInterfaces(),
                    (proxy, method, args) -> {
                        advice.befor(method);
                        Object invoke = method.invoke(target, args);
                        advice.after(method);
                        return invoke;
                    });
        } else {
            //创建一个动态类对象,即增强类对象
            Enhancer enhancer = new Enhancer();
            //确定需要增强的类,设置为父类
            enhancer.setSuperclass(target.getClass());
            //确定代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法
            enhancer.setCallback(this);
            //返回创建的代理对象
            o = enhancer.create();
        }
        return o;
    }

    /**
     * @param o           代理对象本身
     * @param method      被代理对象方法
     * @param objects     被代理对象入参
     * @param methodProxy 可执行代理方法或被代理对象的方法
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        advice.befor(method);
        Object invoke = methodProxy.invokeSuper(o, objects);
        advice.after(method);
        return invoke;
    }
}

执行结果

原文地址:https://www.cnblogs.com/chxwkx/p/14590283.html