手写高仿真Spring框架-AOP部分

手写高仿真Spring框架

流行词:顶层设计 AOP 仿真

参考代码:https://gitee.com/li-lixiang/lean-spring-2.0.git

在前面的blog中,已经实现Spring IOC、DI、MVC,并调试代码展示前后交互结果。接下来学习Spring核心AOP,高仿手写AOP实现逻辑。

顶层设计

实现日志监控

用代理类进行解耦,AopProxy接口,有jdk实现方式与cglib实现方式

JDK实现AopProxy

手写高仿真Spring框架-AOP部分_第1张图片

手写高仿真Spring框架-AOP部分_第2张图片
定义AopProxy,用invoke方法增强原有方法,按照拦截器链去执行增强方法invoke。

 

AOP具体实现

在原有依赖注入的时候,需要增加AOP的情况,优化原有ApplicationContext->refresh->doAutowired->getBean->stantiateBean方法。当需要实例化的类符合切面表达式时,则进行切入(将用proxy增强后的实例代替)。

    private Object instantiateBean(String beanName, GPBeanDefinition gpBeanDefinition) {
        //1、拿到要实例化的对象的类名
        String className = gpBeanDefinition.getBeanClassName();

        //2、反射实例化,得到一个对象
        Object instance = null;
        try {
//            gpBeanDefinition.getFactoryBeanName()
            //假设默认就是单例,细节暂且不考虑,先把主线拉通
            if(this.factoryBeanObjectCache.containsKey(className)){
                instance = this.factoryBeanObjectCache.get(className);
            }else {
                Class clazz = Class.forName(className);
                instance = clazz.newInstance();

                //当需要实例化的类符合切面表达式时,则进行切入(将用proxy增强后的实例代替)
                GPAdvisedSupport config = instantionAopConfig(gpBeanDefinition);
                config.setTargetClass(clazz);
                config.setTarget(instance);
                //符合PointCut的规则的话,创建代理对象
                if(config.pointCutMatch()) {
                    instance = createProxy(config).getProxy();
                }

                this.factoryBeanObjectCache.put(className,instance);
                this.factoryBeanObjectCache.put(gpBeanDefinition.getFactoryBeanName(),instance);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return instance;
    }

 

 

初始化配置

instantionAopConfig

设置方法执行器链

在AdviceSupport->setTargetClass->parse方法中封装方法的拦截器链

 

作业:完成around切面方法拦截器

在切面中增加around方法,在service执行前和执行后执行around方法

实现步骤:

  1. 在application.properties中增加配置如下
    #环绕执行
    aspectAround=around
  2. 在GPAppConfig中增加aspectAround属性
        private String aspectAround;

     

  3. 在GPAdvisedSupport中,增加拦截器链对around方法的切入
    //around
                        if(!(null == config.getAspectAround() || "".equals(config.getAspectAround()))) {
                            //创建一个Advivce
                            advices.add(new GPMethodAroundAdviceInterceptor(aspectMethods.get(config.getAspectAround()),aspectClass.newInstance()));
                        }
  4. 创建类GPMethodAroundAdviceInterceptor 
    /**
     * Copyright (C), 2015-2020, XXX有限公司
     * FileName: GPMethodAroundAdviceInterceptor
     * Author:   lilx
     * Date:     2020/12/5 14:46
     * Description: 环绕执行
     * History:
     *           

     

  5. 完成

 

运行结果:

手写高仿真Spring框架-AOP部分_第3张图片

把其他切面方法注释掉,如下日志

手写高仿真Spring框架-AOP部分_第4张图片

 

 

 

你可能感兴趣的:(Spring,JAVA,spring,aop,java)