美文网首页
AOP底层实现(了解)

AOP底层实现(了解)

作者: 神豪VS勇士赢 | 来源:发表于2018-08-04 23:07 被阅读62次

    两种代理机制:

    • JDK 的动态代理:针对实现了接口的类产生代理。
    • Cglib 的动态代理:针对没有实现接口的类产生代理,应用的是底层的字节码增强的技术 生成当前类的子类对象。

    JDK动态代理
    普通工程,不用加其他依赖。
    使用前提:必须有接口
    面向接口编程。
    第一步:开发目标接口和实现类
    public interface MyJdkDynamicOProxy {
    void addUser();
    }
    public class MyJdkDynamicOProxyImpl implements MyJdkDynamicOProxy {
    @Override
    public void addUser() {
    Log.info("我是动态的代理addUser()方法");
    }
    }

    第二步:开发通知类
    public class MyAdvice {
    public void myAdviceBefore(){
    Log.info("我是 前置 通知 ");
    }
    public void myAdviceAfter(){
    Log.info("我是 后置 通知 ");
    }
    }

    第三步:开发自定义的代理类

    public class MyJdkDynamicOFactory {

        public MyJdkDynamicOProxy  createMyJdkDynamicOProxy(){
            //1,创建目标类对象
            final MyJdkDynamicOProxy myJdkDynamicOProxy =new MyJdkDynamicOProxyImpl();
            //2,创建通知类对象
            final MyAdvice myAdvice =new MyAdvice();
            //3,创建代理类对象,让通知和目标整合
            MyJdkDynamicOProxy myJdkDynamicOProxy1 = (MyJdkDynamicOProxy)Proxy.newProxyInstance(
                    MyJdkDynamicOFactory.class.getClassLoader(),
                    myJdkDynamicOProxy.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            //调用前置通知
                            myAdvice.myAdviceBefore();
                            //唤醒目标方法,就是调用目标方法
                            Object invoke = method.invoke(myJdkDynamicOProxy, args);
                            //调用后置通知
                            myAdvice.myAdviceAfter();
                            return invoke;
                        }
                    }
    
    
            );
            return  myJdkDynamicOProxy1;
        }
    

    }

    注意:
    编写工厂生成代理
    java.lang.reflect.Proxy
    JDK1.8编译匿名内部类参数可以不用加final

    测试以及结果如下所示:


    image.png

    Cglib动态代理
    可以没有接口,只有实现类
    需要加入cglib依赖:


    image.png

    第一步:开发目标类
    没有接口
    public class MyCglibService {
    public void myCglibService(){
    Log.info("我是Cglib 代理 的myCglibService()");
    }
    }

    第二步:开发通知类
    同之前的方式保持一致
    public class MyCglibAdvice {
    public void myAdviceBefore(){
    Log.info("我是 Cglib前置 通知 ");
    }
    public void myAdviceAfter(){
    Log.info("我是 Cglib后置 通知 ");
    }
    }

    第三步:开发代理类
    开发工厂类:编写工厂生成代理
    public class MyCglibProxyFactory {
    public MyCglibService createMyCglibService(){
    //1,创建目标类
    final MyCglibService myCglibService = new MyCglibService();
    //2,创建通知类
    final MyCglibAdvice myCglibAdvice =new MyCglibAdvice();
    //3,创建代理类,整合目标类和通知类,运用AOP
    Enhancer enhancer = new Enhancer();
    //调用父类
    enhancer.setSuperclass(myCglibService.getClass());
    //设置回调加入通知
    enhancer.setCallback(new MethodInterceptor() {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

                    //前置通知
                    myCglibAdvice.myAdviceBefore();
                    Object invoke = method.invoke(myCglibService, objects);
                    myCglibAdvice.myAdviceAfter();
                    return null;
                }
            });
        MyCglibService o = (MyCglibService) enhancer.create();
        return o;
    }
    

    }
    测试代码以及输出结果如下所示:


    image.png

    接下来,我们来分析AOP部分源码:


    image.png
    image.png
    image.png
    image.png

    ctrl+t找实现类
    两种实现方式:

    image.png image.png

    实现相同方法的类如下所示: 进入到相应的类中的方法后 观察源码如上截图所示,
    可以发现 底层源码和我们模拟的AOP一致。


    image.png

    相关文章

      网友评论

          本文标题:AOP底层实现(了解)

          本文链接:https://www.haomeiwen.com/subject/pnhvvftx.html