aop源码解析一:注册BPP
来源:互联网 发布:nemo软件好用吗 编辑:程序博客网 时间:2024/06/08 02:06
如题,标签<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true"/>
注册BPP(AspectJAutoProxyBeanDefinitionParser)源码分析
并没有介绍过BPP相关内容 这里简单的讲解下 读者心里有个概念就行 等有时间补写Bean的加载与读取的时候 会好好介绍这个重要的类!
首先 spring在一些特殊的位置插入了一些处理代码(可能有些读者觉得这句话很眩 不太好理解 我换种表达方式:从加载配置文件到转换成对应的定义类 比如BeanDefinition 再到获取bean 这一整个过程都是spring在做的 他当然能够在任意想插的位置插入代码了) 例如在实例化前后 或者在初始化前后调的方法 这些类一般是BeanPostProcessor的子类 简称BPP
正文
对于aop这样的非标准或者称为自定义命名空间的元素 spring会从spring.handlersspring.handlers文件中的对应关系找到相应的处理类 然后通过init()
方法注册一些处理器 aop命名空间的处理类是AopNamespaceHandler
我们看一下他的init()
方法
public void init() { // In 2.0 XSD as well as in 2.1 XSD. registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser()); // registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser()); registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator()); // Only in 2.0 XSD: moved to context namespace as of 2.1 registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());}
从上面注册的处理器的关系我们知道 <aop:aspectj-autoproxy>
标签的处理器是AspectJAutoProxyBeanDefinitionParser
同样 这是一个继承于BeanDefinitionParser
的标准的解析器 我们看一下他的parse()
方法
public BeanDefinition parse(Element element, ParserContext parserContext) { //注册BPP(AnnotationAwareAspectJAutoProxyCreator) AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element); // 如果有子元素的话 设置属性 extendBeanDefinition(element, parserContext); return null;}
parse()
方法可以说主要做了一件事情就是注册了一个BPP(BeanPostProcessor) 供后续使用
有些人看到这里可能就蒙圈了 这什么东西 名字这么长 看到后面的时候又会说这是什么东西 类的名字这么长 然后就会觉得好难 主要是读者阅读代码不多的原因 如果阅读的多了 你就会形成一个感觉:不管这个类名字多奇怪 名字多长 不过是一些基本类型(map list等)的包装而已 为了完成某一个功能所做的封装而已
//spring中的方法一般都比较清晰 短短的几行代码告诉了你这个方法要做什么事情public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) { //注册BPP(AnnotationAwareAspectJAutoProxyCreator) BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); //根据xml配置 设置AnnotationAwareAspectJAutoProxyCreator的proxyTargetClass exposeProxy属性 useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); //注册组件bean 并暴露给外部 registerComponentIfNecessary(beanDefinition, parserContext);}
不断的追踪registerAspectJAnnotationAutoProxyCreatorIfNecessary()
方法发现 就是注册了个BPP(AspectJAutoProxyBeanDefinitionParser
) 不再贴出相关代码 我们看下useClassProxyingIfNecessary()
方法
//处理proxy-target-class 以及 expose-proxy属性 private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) { if (sourceElement != null) { //proxy-target-class true:强制使用CGLIB代理 推荐使用 boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE)); if (proxyTargetClass) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } //expose-proxy true:暴露代理类 解决某些情况下 代理无法完成的情况 boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE)); if (exposeProxy) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } }}
总结
似乎<aop:aspectj-autoproxy>
标签做的事情并不多 只是注册了一个BPP 但是这个BPP确实非常重要的! 我们用到的切面编程就依靠这个BPP去驱动实现 后面的文章会介绍这个BPP的源码是怎么实现AOP的
- aop源码解析一:注册BPP
- spring源码aop解析(一)
- ARouter解析一:基本使用及页面注册源码解析
- AOP源码解析(一)实现动态代理
- spring源码解析-Aop
- Spring源码解析-aop
- Spring源码解析-AOP
- Eureka 源码解析 —— 应用实例注册发现(一)之注册
- aop源码解析二:postProcessBeforeInstantiation
- aop源码解析三-postProcessAfterInitialization
- spring源码解析-AOP原理
- Spring事务管理(2)-AOP注册解析器
- Spring 源码阅读 AOP一
- Spring基于注解形式的 AOP的原理流程及源码解析(一)
- Spring源码解析之-Aop源码解析(2)
- SSM框架搭建及源码解析--AOP源码解析(五)
- spring-aop源码解析:declare-parent
- spring AOP 源码解析 及其实现原理
- [BZOJ]4689: Find the Outlier 高斯消元
- Languages--CSU-ACM2017暑期训练1-Debug与STL
- UVA 548 Tree(中序+后序还原二叉树)
- HDOJ 6055-Regular polygon
- String,StringBuffer,StringBuilder 三者的讨论
- aop源码解析一:注册BPP
- ios底部输入框输入时被隐藏的bug解决
- 自己总结的html css知识点
- 2017多校第二场 HDU 6047 Maximum Sequence 线段树或者multiset维护区间最值
- 字符串替换
- Spanned及CharSequence
- c# Console.WriteLine() Console.ReadLine()
- aop源码解析二:postProcessBeforeInstantiation
- hibernate的get,load,persist方法比较(二)