随笔 - 24  文章 - 0 评论 - 0 阅读 - 6439
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

首先配置文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--横切逻辑-->
    <bean id="logUtils" class="com.test.circular.LogUtils">
    </bean>
 
    <aop:config>
        <aop:aspect ref="logUtils">
            <aop:before method="beforeMethod" pointcut="execution(public void com.test.aop.AopBean.test())"/>
            <aop:after method="alertMethod" pointcut="execution(public void com.test.aop.AopBean.test())"/>
            <aop:around method="aroundMethod" pointcut="execution(public void com.test.aop.AopBean.test())"/>
            <aop:after-returning method="afterReturning" pointcut="execution(public void com.test.aop.AopBean.test())"/>
            <aop:after-throwing method="afterThrowingMethod" pointcut="execution(public void com.test.aop.AopBean.test())"/>
        </aop:aspect>
    </aop:config>

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class LogUtils {
 
    public void beforeMethod() {
        System.out.println("前置通知");
    }
 
    public void alertMethod() {
        System.out.println("最终通知");
    }
 
    public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕通知-前");
        Object proceed = pjp.proceed();
        System.out.println("环绕通知-后");
 
        return proceed;
    }
 
    public void afterThrowingMethod() {
        System.out.println("异常通知");
    }
 
    public void afterReturning() {
        System.out.println("后置通知");
    }
}

  

public class AopBean implements AopBeanInf{

@Override
public void test() {
System.out.println("spring aop 测试");
}

}

  通过SpringIOC源码中的源码分析过程,可以将切入点定位到如下图所示方法。

 

接着会遍历所有的初始化的bean,主要进入AbstractAutowireCapableBeanFactorydoCreateBean方法,会完成实例创建。

 

往下走会完成bean生命周期的管理,首先属性填充,调用初始化bean,重点分析这个方法。

1) 调用Bean中的BeanNameAware.setBeanName()方法,如果该Bean实现了BeanNameAware接口;调用Bean中的BeanFactoryAware.setBeanFactory()方法,如果该Bean实现了BeanFactoryAware接口,调用Bean中的BeanClassLoader.setBeanClassLoader()方法。

2)调用BeanPostProcessors.postProcessBeforeInitialization()方法

3)调用Bean中的afterPropertiesSet方法,如果该Bean实现了InitializingBean接口;

4)调用Bean中的init-method,通常是在配置bean的时候指定了init-method,例如:<beanclass="beanClass"init-method="init"></bean>

5)调用BeanPostProcessors.postProcessAfterInitialization()方法;

 

实现AOP主要在初始化后应用Bean后置处理器---在这一步生成代理对象

 

这个方法会遍历所有的后置处理器。

 

主要进入AbstractAutoProxyCreator类的postProcessAfterInitialization方法,如下红框所示对象进行包装即增强

 

将所有的通知拆分成数组。

 

如下图所示,通过createProxy方法创建代理对象。

 

进入的createProxy方法,该方法中主要有getProxy这个方法中会通过代理工厂生成对象

 

判断是否实现接口,用jdk还是cglib代理,默认采用jdk代理。
1
2
3
public Object getProxy(@Nullable ClassLoader classLoader) {
       return createAopProxy().getProxy(classLoader);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException("TargetSource cannot determine target class: " +
                    "Either an interface or a target is required for proxy creation.");
        }
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}
1
创建代理对象后,这里采用JdkDynamicAopProxy,然后进入该类的getProxy执行代理方法

 

 观察下JdkDynamicAopProxy这个类,本身实现了InvocationHandler,就是个代理对象,

作为Proxy对象的回调函数被触发,从而通过invoke()的具体实现来完成对目标对象的拦截或者说功能增强的工作。

执行代理对象的invoke方法。

 

 得到拦截链。

 

递归进入了ReflectiveMethodInvocation类的proceed()

 

 可以看到此时的methodName为beforeMethod

 

因此此时会执行MethodBeforeAdviceInterceptor类的invoke方法。

 

 继续往下走,一直到AbstractAspectJAdvice类的如下方法:

 

通过反射执行Method

 

 

执行到DelegatingMethodAccessorImpl类的invoke方法。

 

执行到NativeMethodAccessorImpl类中invoke方法。

 

 继续执行会到走到前置通知方法答应出具体内容。

 

返回,执行完前置通知后再调用mi.proceed()。

 

接着从执行链中再取一个执行。

 

进入AspectJAfterAdvice类执行最终通知

 

 

环绕通知,创建了连接点对象,执行到AspectJAroundAdvice类的invoke方法

 

 

 

 

进入proceed,执行后置通知

 

 

AfterReturningAdviceInterceptor

 

执行连接点之后进行后置通知,首先执行连接点方法

 

 

这时找到异常通知

在AspectJAfterThrowingAdvice类

 

 

执行目标方法

 

 

 

然后返回 

 

 

执行后置通知

 

 

 

最后在finally中执行最终通知。

 

 

posted on   jeolyli  阅读(50)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示