‘壹’ spring-AOP(二) 自动代理
下图是AOP自动代理的流程图
spring中已经定义了创建代理的工厂类 ProxyFactory,通过 ProxyFactory 创建代理,必须要一个被代理对象和一个增强Advisor列表
spring的动态代理实质就是对象创建完毕之后,查找筛选能够应用于该对象上的Advisor列表,然后调用ProxyFactory创建代理对象返回。
Spring中定义了 AbstractAutoProxyCreator 类用于实现自动代理。
从继承图可以看出该类实现了 BeanPostProcessor 接口,覆写了 方法。spring的bean初始化完成后会遍历注册的所有BeanPostProcessor实现类对象,调用其方法,该方法可以返回一个新的对象覆盖原有对象,在此spring提供一个创建代理并覆盖被代理对象的机会
遍历容器中注册的所有BeanPostProcessor,调用方法,如果返回一个新的对象会覆盖掉原始对象注册到spring容器中
上面分析了AbstractAutoProxyCreator是实现自动代理的关键,那么在spring中如何配置一个AbstractAutoProxyCreator的实现类对象呢,spring又是如何根据配置注册该对象的
在spring中可以通过两种配置,启动自动代理
这两中方法最终都是向spring容器中注册了一个实例,这样在spring初始化完对象后就可以调用的方法了
上面分析了spring是在何时何处开始创建代理的,解下来分析AbstractAutoProxyCreator进行自动代理的总体实现
在方法中判断 被代理对象不为空,调用wrapIfNecessary判断是否对目标类进行代理
createProxy方法中通过ProxyFactory设置AOP配置,如被代理对象和Advisor列表,调用getProxy创建代理对象。
至此AbstractAutoProxyCreator完成了自动创建代理的总体实现,在该抽象类中没有实现获取Adviso列表r的功能,交由各个子类去实现。
分析完spring自动代理的整体实现,接下来看下AbstractAutoProxyCreator的子类是如何进行查找 Advisor、筛选Advisor、排序Advisor的。
实现了getAdvicesAndAdvisorsForBean方法,用于获取应用于目标类的Advisor列表
在findEligibleAdvisors方法定义了查找 Advisor、筛选Advisor、排序Advisor三步操作
在spring中可以通过注册Advisor的bean来实现对目标类的增强代理。spring会筛选出容器中所有Advisor类型的bean,用于对容器中的对象进行增强代理,查找的功能由类实现
将查找功能委托给advisorRetrievalHelper()实现,该方法的功能就是获取Advisor类型的bean对象返回
spring除了支持配置或者手动注册 Advisor类型的bean之外,还支持通过 @Aspect、@Before、@After等AOP注解来声明Advisor。Advisor的查找解析由子类实现
在的findCandidateAdvisors方法中,第一步首先调父类的方法获取到容器中注册的所有Advisor,然后再委托aspectJAdvisorsBuilder解析注解获取Advisor,然后合并两个结果返回
.buildAspectJAdvisors方法解析AOP注解封装为Advisor对象。
spring定义了一个AspectJAdvisorFactory接口用于解析AOP的注解,接口主要定义了两个功能
AspectJAdvisorFactory的实现类提供了具体实现
调用getAdvisor方法,获取通知方法上的Pointcut表达式,如果在方法上未解析到Pointcut,则跳过,然后根据通知方法和对应Pointcut封装返回一个Advisor的实现类对象
解析获取通知方法的Pointcut表达式,在该方法中会过滤掉不带Aop注解的非通知型方法,判断一个方法是不是通知就是判断该方法是否声明了切点
最终封装返回的Advisor是类型,在该实现类的getAdvice方法会回调中的getAdvice方法,会根据通知方法上不同的注解,创建对应的Advice
回调中的getAdvice,策略创建对应的Advice实现类对象
获取到spring容器中所有的Advisor之后,再回到类中,接下来筛选能够应用到目标对象的Advisor。通过Advisor中的Pointcut的ClassFilter和MethodMatcher来对目标对象进行匹配。 在这个阶段的筛选,只要Advisor能应用到目标类型的任意一个方法上都会返回成功
接下来看.findAdvisorsThatCanApply方法,将筛选的工作委托给AopUtils来实现
AopUtils.findAdvisorsThatCanApply方法中遍历所有的Advisor,然后调用canApply方法判断是否符合,在当中会区分引介增强和切点增强,引介增强是类级别的,只需要根据切点的ClassFilter对目标类进行判断就行。
canApply方法中,通过Pointcut来进行匹配,引介增强IntroctionAdvisor直接根据其ClassFilter判断目标类型,PointcutAdvisor根据其中的Pointcut来进行筛选
Pointcut会首先使用ClassFilter对目标类型进行过滤。如果通过,再使用 MethodMatcher 校验 类中所有的方法,只要有一个方法匹配上,代表该Advisor符合条件。
在这里宁可多通过,也不要校验太严格,因为在代理类中具体方法执行的时候,还会再一次使用Pointcut进行校验。所以该方法中会获取目标类型的所有接口,判断接口中的方法,有一个符合也会返回true
当获取到目标类型上的所有Advisor后,还需要对Advisor进行排序。Advisor的顺序决定了通知方法的应用顺序。
Advisor的排序主要分为两种
接下来看下spring是怎么实现排序的
.sortAdvisors提供了基于Ordered的排序,由spring的统一处理Ordered实现类或者添加@Ordered注解类的排序
覆写了父类的sortAdvisors方法,在基于Ordered排序基础上提供了同一切面下不同通知之间的排序,具体排序实现委托给了PartialOrder
至此完成Advisor的查找、筛选、排序。
‘贰’ 2020-07-26 带着疑问看源码 -- springboot aop默认采用什么动态代理机制
了解springboot aop的动态代理方式有哪些种类?
有3种,前提均开启spring.aop.auto=true:
1. jdk动态代理:当spring.aop.proxy-target-class=false, 引入了aspectjweaver依赖时生效
2. cglib代理:当spring.aop.proxy-target-class=true, 引入了aspectjweaver依赖时生效
3. 基础代理:当spring.aop.proxy-target-class=true, 若没有aspectjweaver依赖时生效,只作用于框架内部的advisors,
我们既然用springboot那么就采用springboot的AopAutoConfiguration自动配置类来加载aop机制的,内部对@EnableAspectJAutoProxy进行了封装,扩展了一些配置项,同时还提供了ClassProxyingConfiguration配置(下面会讲到).
这个自动装配类会是spring boot框架自动会装配的,所以说默认aop机制是打开的,可以通过配置项:spring.aop.auto=false 手工关闭。
这个配置类会根据spring.aop.proxy-target-class配置项来决定采用jdk动态代理或者cglib动态代理:
注意:配置类生效前提是@ConditionalOnClass(Advice.class),说明只有当引入了依赖项才生效:
而这里推荐使用spring-boot-starter-aop来传递依赖:
这里我们已经看到提供了原生spring的两种代理方式,接着看AopAutoConfiguration源码发现还有个ClassProxyingConfiguration配置类,其生效条件之一是@ConditionalOnMissingClass("org.aspectj.weaver.Advice"),就是当项目里没有aspectjweaver的依赖的时候生效。
我们进入AopConfigUtils.(registry)方法,通过几步调用跳转:
发现会去注册后置处理器,查看源码注释:
表明了只为基础的advisor做动态代理,而忽略应用定义的Advisors,说明项目中我们自定义的切面是不会被AOP代理的。
‘叁’ Spring中的ioc和aop有什么作用为什么要用ioc和aop面试中多次被问到,求一个详细 清晰的解答...
还是需要去了解,多看看书!
IOC:控制反转,是一种设计模式。一层含义是控制权的转移:由传统的在程序中控制依祥橡纤赖转移到由容器来控制;第谨仿二层是依赖注入:将相互依赖的对象分离,在spring配置文件中描述他们的依赖关系。他们的依赖关系只在使用的时候才建立。简单来说就是不需要NEW一个对象了。
AOP:面向切面,是一种编程思想,OOP的延续。将系统中非核心的业务提取出来,进行单如汪独处理。比如事务、日志和安全等。这个简单来说就是可以在一段程序之前或者之后做一些事。
Spring 的AOP和IOC都是为了解决系统代码耦合度过高的问题。使代码重用度高、易于维护。
不过AOP和IOC并不是spring中特有的,只是spring把他们应用的更灵活方便
‘肆’ 什么是aop,aop的作用是什么
aop是面向切面的编程。 它可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。 如果您学习Java的话,会在Spring中经常用到,那是你更能领悟它!
‘伍’ spring aop是使用什么代理模式
采用JAVA 动态代理设计模式设计的,目前主要应用于 事务,有了 Spring的 声州滚明式事务可以 对程序员编码的代码量减少很辩碧多,册灶余不用每层的持久化方法都自己控制事务
‘陆’ aop原理。是动态代理
AOP是Aspect Oriented Programming的简写,中文意思是面向方面编程。
AOP的核心是方面,关注点是将共通操作提取,动态的作用的某一批目标对象上,
作用:用于改善共通逻辑和目标组件逻辑的分离,降低耦合。如Spring的声明式事务管理就是采用AOP机制实现的。
Spring AOP采用的是动态代理技术实现,分两种:
1,CGLIB开发包,目标组件没有接口,AOP动态生成新的类型继承目标组件,重写目标组件方法来实现调用方面处理的操作,
2,实现目标组件的接口。
手打求采纳啊