AOP增强、JDK代理、cglib代理

AOP增强

aop除了代理增强之外还有其他的增强

方式一:ajc增强,没有利用到spring容器,而是用了ajc编译器来增强

方式二:agent类加载增强

aop代理增强-jdk的动态代理

是jdk自带的代理功能,只能针对接口代理。

产生代理需要用到jdk的Proxy中的newProxyInstance方法。

参数1-类加载器:因为相比于正常编写的Java代码,代理对象的生成是没有源码的,是在运行期间直接生成字节码文件,所以就需要一个类加载器去加载这个字节码文件

参数2-要实现的接口

参数3-invocationHandler接口:代理类创建出来,也实现了接口,还要实现接口中方法,这些方法的封装就封装在invocationHandler接口里面,具体的执行是invocationHandler接口的invoke方法。

        这个invoke方法又有三个参数:

  • proxy:代理对象自己
  • method:正在执行的方法对象
  • args:方法传过来的参数
public static void main(String[] param) throws IOException {
        // 目标对象
        Target target = new Target();

        ClassLoader loader = JdkProxyDemo.class.getClassLoader(); // 用来加载在运行期间动态生成的字节码
        Foo proxy = (Foo) Proxy.newProxyInstance(loader, new Class[]{Foo.class}, (p, method, args) -> {
            System.out.println("before...");
            // 目标.方法(参数)
            // 方法.invoke(目标, 参数);
            Object result = method.invoke(target, args);
            System.out.println("after....");
            return result; // 让代理也返回目标方法执行的结果
        });

        System.out.println(proxy.getClass());

        proxy.foo();

        System.in.read();
    }
}
  • 在jdk的动态代理中目标对象和代理对象是兄弟关系,所以不可以强制转换
  • 目标对象可以是final对象

 aop代理增强-cglib的动态代理

通过enhance类的create方法来创建代理对象,cglib通过父子继承关系来实现动态代理,所以create的两个参数

参数1:需要继承的父类,即目标对象的类

参数2:MethodInterceptor,类似于jdk中的invocationHandler接口,封装的是代理对象方法执行时的行为

这个接口的有四个参数

参数1:代理类自己

参数2:代理类中的方法

参数3:方法传过来的对象

参数4:可以认为是一个方法对象,可以避免反射调用

public class CglibProxyDemo {

    static class Target {
        public void foo() {
            System.out.println("target foo");
        }
    }

    // 代理是子类型, 目标是父类型
    public static void main(String[] param) {
//        Target target = new Target();

        Target proxy = (Target) Enhancer.create(Target.class, (MethodInterceptor) (p, method, args, methodProxy) -> {
            System.out.println("before...");
//            Object result = method.invoke(target, args); // 用方法反射调用目标
            // methodProxy 它可以避免反射调用
//            Object result = methodProxy.invoke(target, args); // 内部没有用反射, 需要目标 (spring)
            Object result = methodProxy.invokeSuper(p, args); // 内部没有用反射, 需要代理
            System.out.println("after...");
            return result;
        });

        proxy.foo();

    }
}

代理类是子类,目标类是父类,所以目标类不能是final,不然代理类不能继承,同时目标类中方法也不能是final字段,因为子类重写了父类的方法,加了就不能重写了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值