SpringAOP 动态代理

1.实现方式:JDK动态代理和CGLIB动态代理

2.动态代理特点

1.目标对象不固定
2.在应用程序执行时动态创建目标对象
3.代理对象会增强目标对象的行为

3.JDK动态代理

package com.xxx.proxy;

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

/**
 * JDK动态代理类
 */
public class JDKHandler implements InvocationHandler {

    //目标对象 类型不固定 创建时动态生产
    private Object target;
    //通过带参构造传递目标对象
    public JDKHandler(Object target) {
        this.target = target;
    }


    /**
     * 1.调用目标对象方法(返回object)
     * 2.增强目标对象行为
     * @param proxy 调用方法代理实例
     * @param method 目标对象方法
     * @param args  目标对象方法需要的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //增强行为
        System.out.println("before");

        Object object=method.invoke(target,args);

        return object;
    }



    public Object getProxy(){
        /**
         * 三个参数:Classloader loader,Class[] interface, InvocationHandler h
         *      loader:类加载器
         *      interface:接口数组
         *      h:接口的实现类
         */
        Object object= Proxy.newProxyInstance(this.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);

        return object;
    }
}

实现方法

 public static void main(String[] args) {
        Man man=new Man();
        JDKHandler jdkHandler=new JDKHandler(man);
        //得到代理对象
        Marry marry=(Marry) jdkHandler.getProxy();
        //执行invoke()
        marry.toMarry();
    }

4.CGLIB动态代理

区别

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能使用JDK的动态代理
cglib是针对类来实现代理的,它的原理是对指定的目标类生成一个子类, 并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
JDK动态代理实现接口,Cglib动态代理继承思想
JDK动态代理(目标对象存在接口时)执行效率高于Ciglib
如果目标对象有接口实现,选择JDK代理,如果没有接口实现选择Cglib代理


public class cglibInterceptor implements MethodInterceptor {
    //目标对象
    private Object target;
    //通过构造器传入目标对象
    public cglibInterceptor(Object target) {
        this.target = target;
    }

    //获取代理对象
    public Object getProxy(){
        //通过Enhancer对象中的create()方法生成一个类,用来代理对象
        Enhancer enhancer =new Enhancer();
        //设置父类 将目标类作为代理类的父类
        enhancer.setSuperclass(target.getClass());
        // 设置拦截器 回调对象为本身对象
        enhancer.setCallback(this);
        // 生成代理对象并返回
        return enhancer.create();
    }

    /**
     * 拦截器
     *  1.目标对象的方法调用
     *  2.行为增强
     * @param o     cgilb动态生产的代理类实例
     * @param method        实体类所调用的都被代理的方法的引用
     * @param objects       参数列表
     * @param methodProxy   生产的代理类对方法的代理引用
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //调用目标类中的方法
        Object object=methodProxy.invoke(target,objects);
        //增强行为
        return null;
    }
}

实现

 public static void main(String[] args) {
        //得到目标对象
        Dog d=new Dog();
        //得到拦截器
        CglibInterceptor cglibInterceptor=new CglibInterceptor(d);
        //得到代理对象
        Aninmal aninmal=(Aninmal) cglibInterceptor.getProxy();
        //通过代理对象调用目标对象的方法
        aninmal.fun();

        //没有接口实现的类 JDK代理不可以实现
        User user=new User();
        CglibInterceptor cglibInterceptor1=new CglibInterceptor(user);
        User u=(User) cglibInterceptor1.getProxy();
        u.test();
    }
posted @ 2022-07-15 19:27  lwx_R  阅读(24)  评论(0编辑  收藏  举报