Spring的AOP实现

本文深入探讨了Spring AOP的实现过程,从配置文件解析到动态代理的创建。通过分析`AopNamespaceHandler`、`AspectJAutoProxyBeanDefinitionParser`、`AnnotationAwareAspectJAutoProxyCreator`等关键类,揭示了如何根据@AspectJ注解生成代理,并详细解释了JDK动态代理的创建逻辑,包括拦截器链的执行流程。
摘要由CSDN通过智能技术生成

如果需要在Spring中使用AOP是非常简单的,只需要在Bean上加上@AspectJ,在方法上加@PointCut、@Before等注解就可以实现你想要的逻辑,最后在XML配置文件中加入<aop:aspectj-autoproxy>即可。

那么Spring是如何实现的呢?

动态AOP标签

我们从AopNamespaceHandler中的init()方法开始分析:

1.配置文件中在遇到aspectj-autoproxy标签的时候我们会采用AspectJAutoProxyBeanDefinitionParser解析器

2.进入AspectJAutoProxyBeanDefinitionParser的parse方法,它将请求给了AopNamespaceUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary去处理

3.registerAspectJAnnotationAutoProxyCreatorIfNecessary方法中,先调用AopConfigUtils的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法完成注册或者升级AnnotationAwareAspectJAutoProxyCreator类。对于AOP的实现,基本是靠AnnotationAwareAspectJAutoProxyCreator去完成的,它可以根据@point注解定义的切点来代理相匹配的bean。

4.接下来会调用useClassProxyingIfNecessary() 处理proxy-target-class以及expose-proxy属性

5.最后的调用registerComponentIfNecessary 方法,注册组建并且通知便于监听器做进一步处理。

2.创建AOP代理

AOP主要是依靠AnnotationAwareAspectJAutoProxyCreator的实现的。那么AnnotationAwareAspectJAutoProxyCreator是如何完成的?

AnnotationAwareAspectJAutoProxyCreator的层次结构:

这里写图片描述

AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口,那就意味着这个类在spring加载实例化前会调用postProcessAfterInitialization方法。

public Object <strong>postProcessAfterInitialization</strong>(Object bean, String beanName) throws BeansException {  
    if (bean != null) {  
        Object cacheKey = getCacheKey(bean.getClass(), beanName);  
        if (!this.earlyProxyReferences.containsKey(cacheKey)) {  
            return wrapIfNecessary(bean, beanName, cacheKey);  
        }  
    }  
    return bean;  
}  

逻辑:
1.根据bean的class和name生成一个key。
2.如果适合代理就执行wrapIfNecessary(bean, beanName, cacheKey)。

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {  
        if (beanName != null && this.targetSourcedBeans.containsKey(beanName)) {  
            return bean;  
        }  
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {  
            return bean;  
        }  
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {  
            this.advisedBeans.put(cacheKey, Boolean.FALSE);  
            return bean;  
        }  
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);  
        if (specificInterceptors != DO_NOT_PROXY) {  
            this.advisedBeans.put(cacheKey, Boolean.TRUE);  
            Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));  
            this.proxyTypes.put(cacheKey, proxy.getClass());  
            return proxy;  
        } 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值