Spring AOP源码分析
4 Spring AOP
4.1 AOP功能测试
AOP是指运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式,AOP的本质是动态代理
1、导入Spring的AOP模块
2、定义一个业务逻辑类MathCalculator:在业务逻辑运行的时候将日志进行打印(方法运行开始、方法运行结束、方法出现异常)
3、定义一个日志切面类LogAspects:切面类里的方法需要动态感知MathCalculator运行到那里了
通知方法 | 作用 | 注解 |
---|---|---|
前置通知 | 在目标方法运行之前运行 | @Before |
后置通知 | 在目标方法运行之后运行,无论是正常结束还是异常结束 | @After |
返回通知 | 在目标方法正常返回之后运行 | @AfterReturning |
异常通知 | 在目标方法出现异常以后运行 | @AfterThrowing |
环绕通知 | 动态代理,手动推进目标方法运行 joinPoint**.**procced() | @Around |
4、给目标类加通知注解
5、将切面类和目标方法所在类都加入到Spring容器中
6、告诉Spring容器哪个是切面类
7、开启基于注解的Aop模式
1、加入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
2、业务类
public class MathCalculator {
public int div(int i,int j) {
System.out.println("目标方法执行:------->");
return i / j;
}
}
3、切面类
@Aspect
public class LogAspects {
//抽取公共的切入点表达式
@Pointcut("execution(public int aop.MathCalculator.*(..))")
public void pointCut(){}
@Before("execution(public int aop.MathCalculator.div(int, int))")
public void logStart(JoinPoint joinPoint){
List<Object> list = Arrays.asList(joinPoint.getArgs());
System.out.println("前置通知:运行参数是" + joinPoint.getSignature()+":"+list.toString());
}
@After(value = "pointCut()")
public void logEnd(JoinPoint joinPoint){
System.out.println("后置通知:除法运行结束" + joinPoint.getSignature());
}
@AfterReturning(value = "pointCut()",returning = "result")
public void logReturn(JoinPoint joinPoint,Object result){
System.out.println("返回通知:除法正常运行结束,运行结果"+ joinPoint.getSignature()+":"+result);
}
@AfterThrowing(value = "aop.LogAspects.pointCut()",throwing = "expection")
public void logExpection(JoinPoint joinPoint,Exception expection){
System.out.println("异常通知:除法运行结束,异常信息"+joinPoint.getSignature()+":" + expection);
}
}
4、配置类
@EnableAspectJAutoProxy
@Configuration
public class AopConfig {
@Bean
public MathCalculator mathCalculator(){
return new MathCalculator();
}
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
5、测试类
public class AopTest {
@Test
public void test1() {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AopConfig.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String s : beanDefinitionNames) {
System.out.println(s);
}
System.out.println("------");
MathCalculator mathCalculator = (MathCalculator) applicationContext.getBean("mathCalculator");
mathCalculator.div(2, 3);
}
}
6、结果
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
aopConfig
mathCalculator
logAspects
org.springframework.aop.config.internalAutoProxyCreator
------
前置通知:运行参数是int aop.MathCalculator.div(int,int):[2, 3]
目标方法执行:------->
后置通知:除法运行结束int aop.MathCalculator.div(int,int)
返回通知:除法正常运行结束,运行结果int aop.MathCalculator.div(int,int):0
Process finished with exit code 0
将 测试的除数改为0
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
aopConfig
mathCalculator
logAspects
org.springframework.aop.config.internalAutoProxyCreator
------
前置通知:运行参数是int aop.MathCalculator.div(int,int):[2, 0]
目标方法执行:------->
后置通知:除法运行结束int aop.MathCalculator.div(int,int)
异常通知:除法运行结束,异常信息int aop.MathCalculator.div(int,int):java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
at aop.MathCalculator.div(MathCalculator.java:11)
at aop.MathCalculator$$FastClassBySpringCGLIB$$c5e409b6.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
......
Process finished with exit code -1
4.2 AOP原理-1
AOP的主要原理是开启AOP代理,也就是 @EnableAspectJAutoProxy注解的功能
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
而该注解主要是使用@ Import导入一个类AspectJAutoProxyRegistrar.class
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
//把@EnableAspectJAutoProxy 注解属性值拿过来,做判断,并做一些事情配置
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
这个类实现了ImportBeanDefinitionRegistrar接口,用来给Spring容器中自定义导入类,首先看
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
做了哪些工作
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
这个类的主要工作是,给Spring容器中注入一个Bean
Bean(id:"org.springframework.aop.config.internalAutoProxyCreator",
class = "AnnotationAwareAspectJAutoProxyCreator")
这个Bean的主要作用是:自动代理创建器AnnotationAwareAspectJAutoProxyCreator
注意:
@Enabel*****
主要是看给容器中注册了什么组件,这个组件什么时候开始工作,以及组件的主要功能是什么
再来看一下整个组件的的类继承结构
class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator
class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator
class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator
class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
SmartInstantiationAwareBeanPostProcessorBean的后置处理器和BeanFactoryAware接口(之前分析过),后置处理器是Ban完成初始化前后做事情,BeanFactoryAware用来给Bean装配BeanFactory
4.3 AOP原理-2
AbstractAutoProxyCreator 里边有
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
AbstractAdvisorAutoProxyCreator重写了setBeanFactory方法
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
AspectJAwareAdvisorAutoProxyCreator没有重写方法
AnnotationAwareAspectJAutoProxyCreator 重写了AbstractAdvisorAutoProxyCreator中的 initBeanFactory方法
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
4.4 AOP原理-3注册AnnotationAwareAspectJAutoProxyCreator
打断点,运行测试类
1、传入配置类,创建IOC容器
2、注册配置类,调用refresh()刷新容器
3、注册bean的后置处理器来方便拦截bean的创建
1)、先获取IOC容器中已经定义好了的需要创建对象的所有BeanPostProcessor,因为开启了自动代理的注解,就会创建AnnotationAwareAspectJAutoProxyCreator类,而这个类间接实现了SmartInstantiationAwareBeanPostProcessor,所以可以获取到名为internalAutoProxyCreator的Processor,类型是AnnotationAwareAspectJAutoProxyCreator
2)、给容器中添加其他的Processor
3)、优先注册实现了PriorityOrdered接口的Processor
4)、再注册实现了Ordered接口的Processor(AnnotationAwareAspectJAutoProxyCreator间接实现了)
5)、最后注册没有实现排序接口的Processor
6)、注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中
4、创建internalAutoProxyCreator的Bean,AnnotationAwareAspectJAutoProxyCreator类型的
1)、创建Bean的实例
2)、populateBean;给bean的各种属性赋值
3)、initalizeBean:初始化Bean包括:
第一步、invokeAwareMethods 处理Aware的辅助
第二步、applyBeanPostProcessorsBeforeInitialization调用后置处理器before方法
第三步、invokeInitMethods 执行bean的初始化方法
第四步、applyBeanPostProcessorsAfterInitialization调用后置处理器after方法
5、AnnotationAwareAspectJAutoProxyCreator类型的BeanProcessor创建成功
6、把BeanProcessor创建到BeanFactory中
4.5 AOP原理-4AnnotationAwareAspectJAutoProxyCreator的执行时机
以上都是分析的AnnotationAwareAspectJAutoProxyCreator的创建过程,它的本质就是一个Processor,那么它创建完成之后,其他的bean创建的时候就会起作用,接下来分析它是如何起作用的,
AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator 实现了SmartInstantiationAwareBeanPostProcessor接口,这个接口又见接继承了之前分析的BeanPostProcessor,是一种特殊的PostProcessor,其抽象方法如下:
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
1、初始化剩余的单实例Bean
AnnotationConfigApplicationContext构造方:
finishBeanFactoryInitialization()
2、获取所有的单实例的bean名:
/ Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
//调用getBean方法
getBean(beanName);
}
}
}
3、先检查单实例bean是否已经被注册,否则才创建
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
4、创建bean
这块意思是给后置处理器一个机会来创建返回代理对象,如果能返回就使用代理对象,否则继续调用CreateBean,走创建Bean的流程:创建bean实例,bean的属性赋值,然后初始化bean、初始化的时候先执行aware方法,然后执行Proccessor的before和after方法
注意:
1、BeanPostProcessor是在Bean对象创建完成初始化前后调用的
2、InstantiationAwareBeanPostProcessor是创建Bean实例之前先尝试使用特殊后置处理器返回对象的
4、执行resolveBeforeInstantiation方法
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//这块判断的InstantiationAwareBeanPostProcessor正好是SmartInstantiationAwareBeanPostProcessor的父类
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
然后就到了打断点的地方。。。
4.6 AOP原理-5 创建AOP代理对象
之前已经分析了每一个Bean创建之前,都会尝试去调用InstantiationAwareBeanPostProcessor的方法去创建代理对象。
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
//判断当前bean是否在advisedBeans当中(advisedBeans中保存了所有需要增强的bean)
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
关心MathCalculator和LogAspects的创建
1、判断当前前Bean是否在targetSourcedBeans中(保存了所有需要增强的bean)
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
2、判断当前Bean是否是基础类型的(Advice、Pointcut、Advisor、AopInfrastructureBean)
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
由于AnnotationAwareAspectJAutoProxyCreator对该方法进行了重写:
@Override
protected boolean isInfrastructureClass(Class<?> beanClass) {
// Previously we setProxyTargetClass(true) in the constructor, but that has too
// broad an impact. Instead we now override isInfrastructureClass to avoid proxying
// aspects. I'm not entirely happy with that as there is no good reason not
// to advise aspects, except that it causes advice invocation to go through a
// proxy, and if the aspect implements e.g the Ordered interface it will be
// proxied by that interface and fail at runtime as the advice method is not
// defined on the interface. We could potentially relax the restriction about
// not advising aspects in the future.
return (super.isInfrastructureClass(beanClass) || this.aspectJAdvisorFactory.isAspect(beanClass));
}
所以这块还要判断是否为为Aspect类型
public boolean isAspect(Class<?> clazz) {
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
}
private boolean hasAspectAnnotation(Class<?> clazz) {
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
}
3、是否需要跳过
AspectJAwareAdvisorAutoProxyCreator重写了Skip方法
(1)、获取候选的增强器(切面里的通知方法),是InstantiationModelAwarePointcutAdvisor类型
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
//candidateAdvisors就是四个通知方法
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor) {
if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
return true;
}
}
}
return super.shouldSkip(beanClass, beanName);
}
都不是AspectJPointcutAdvisor类型,永远返回false
4、创建ben
@Bean
public MathCalculator mathCalculator(){
return new MathCalculator();
}
5、调用postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
7、调用wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(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;
}
// Create proxy if we have advice.
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;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
1、获取当前bean的所有增强器
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
//获取到候选的增强器
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
2、找到可用的增强器(能在当前bean使用的增强器,即哪些通知方法是可以切入当前方法的)
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//candidateAdvisors 就是四个通知方法
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
//开始查找
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
//计算每个切入点表达式是否匹配
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
3、返回可用的增强器
1、找到候选的所有增强器(通知方法)
2、获取到能在当前bean使用的增强器
4、给增强器排序
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
5、返回 Object[] specificInterceptors
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
6、保存当前bean在advisedBeans中
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(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;
}
// Create proxy if we have advice.
//拿到增强器数组
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果当前bean需要代理增强
if (specificInterceptors != DO_NOT_PROXY) {
//保存当前bean在advisedBeans,表示当前前bean已经背增强处理了
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
7、创建代理对象
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//拿到增强器
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
//将增强器放到代理工厂
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
}
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
public Object getProxy(ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
@Override
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)) {
//创建JDK动态代理
return new JdkDynamicAopProxy(config);
}
//创建CgLIB动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
Spring自动决定创建JDK还是CGlib的动态代理
最终给容器中返回当前组件使用CGLIB增强了的代理对象
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
4.7 AOP原理-6 获取拦截器链
容器中保存了组件的代理对象(CGLib增强后的对象),这个对象里边保存了详细信息(比如增强器、目标对象等)
端点进入,就进入到 intercept方法
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Class<?> targetClass = null;
Object target = null;
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be null. Get as late as possible to minimize the time we
// "own" the target, in case it comes from a pool...
//此处的target就是计算类MathCacultor
target = getTarget();
if (target != null) {
targetClass = target.getClass();
}
//advised就是ProxyFactory,此处是根据ProxyFactory获取目标方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
//如果没有拦截器链条,直接执行目标方法
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
//否则我们创建一个CglibMethodInvocation对象,把需要执行的目标对象、目标方法,拦截器链等信息传入创建一个CglibMethodInvocation对象,并调用procced方法
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null) {
releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
1、根据ProxyFactory获取拦截器链
CglibAopProxy的intercept方法
//获取目标方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
//一个默认的拦截器和4个增强器,长度为5的List
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
//遍历所有的增强器封装成interceptor
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
//将增强器转为MethodInterceptor
List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
//如果不是使用AdvisorAdapter适配器转换
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
2、如果没有拦截器链,直接执行目标方法
3、如果有拦截器链
每一个通知方法都被包装成方法拦截器,利用MehodInteceptor
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
//将拦截器链传递进来进行proceed调用
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
4.8 AOP原理-7 链式调用通知方法
链式调用每一个拦截器,调用Invok方法(每个连接器等待下一个拦截器执行完成并返回后再来执行),用来保证拦截器链的执行顺序
@Override
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
//currentInterceptorIndex 默认值为-1 判断 -1 ?== 5-1
//有两种情况执行invokeJoinpoint(),第一种,没有拦截器链,-1 == 0-1
//第二种情况: 4 = 5-1 4表示当前拦截器链的索引为4,即执行到了最后一个拦截器
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
//链式调用
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
1、初始的默认拦截器只是为了给当前线程ThreadLocal中放入代理对象
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
invocation.set(mi);
try {
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
2、索引加1来到 AspectJAfterThrowingAdvice
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}
3、索引加1来到AfterReturningAdviceInterceptor
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
4、索引加1来到AspectJAfterAdvice
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
//无论如何后置方法都会执行
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
5、索引加1来到MethodBeforeAdviceInterceptor
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//前置方法执行完
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
//目标方法执行
return mi.proceed();
}
所以,如果目标方法有异常,返回通知不会执行,异常被异常通知捕获。如果没有异常,返回通知才会执行
4.9 AOP总结
1、@EnableAspectJAutoProxy 开启AOP功能
2、@EnableAspectJAutoProxy 给容器中注入了一个AnnotationAwareAspectJAutoProxyCreator,是一个后置处理器
3、容器的创建
1)、registerBeanPostProcessors(beanFactory);注册后置处理器创建AnnotationAwareAspectJAutoProxyCreator
2)、finishBeanFactoryInitialization初始化剩下的单实例bean,创建bean的时候,会创建业务组件和切面组件,
3)AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程,再来判断组件是否需要增强,是的话:切面的通知方法,包装成增强器(Advisor),给业务组件生成代理
4、执行目标方法
1)、代理对象执行目标方法
2)、CglibAopProxy的intercept方法
3)、得到目标方法的执行器链(增强器包装成MethodInterceptor)
4)、利用拦截器的链式机制,依次进入每一个拦截器进行执行;
5)、效果 :
正常执行:前置通知->目标方法->后置通知->返回通知
出现异常:前置通知->目标方法->后置通知->异常通知