AOP是面向切面编程,能对一些方法进行相同的处理。首先来看一下怎么用。
①创建一个需要被拦截的bean
public class AopTest {
public void test(){
System.out.println("test");
}
}
②创建一个Advisor
package advisor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
/**
* Created by Administrator on 2017/8/20 0020.
*/
@Aspect
public class AspectJTest {
@Pointcut("execution(* *.test(..))")
public void test(){
}
@Before("test()")
public void beforeTest(){
System.out.println("start test");
}
@After("test()")
public void afterTst(){
System.out.println("end test");
}
@Around("test()")
public Object aroundTest(ProceedingJoinPoint point){
System.out.println("开始环绕");
Object o = null;
try {
o = point.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("结束环绕");
return o;
}
}
③配置xml文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<aop:aspectj-autoproxy/>
<bean id="test" class="bean.AopTest"/>
<bean class="advisor.AspectJTest"/>
</beans>
④测试
@Test
public void testSimpleLoad(){
ApplicationContext context = new ClassPathXmlApplicationContext("beanFactoryTest.xml");
AopTest aopTest = (AopTest) context.getBean("test");
aopTest.test();
}
结果:
开始环绕
start test
test
结束环绕
end test
现在来分析这个aop
还记得这之前的自定义标签解析了,在碰到自定义标签时,会通过命名空间找到命名空间处理器,然后调用init方法,注册这个解析器,最后进行标签解析,我们找到映射
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
进入这个命名空间处理器
public void init() {
this.registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
this.registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
this.registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
this.registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
看到了他的init方法,正是注册了一个AspectJAutoProxyBeanDefinitionParser解析器,找到parse方法
public BeanDefinition parse(Element element, ParserContext parserContext) {
//注册AspectJAnnotationAutoProxyCreator AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
//对注解子类进行处理
this.extendBeanDefinition(element, parserContext);
return null;
}
我们进入registerAspectJAnnotationAutoProxyCreatorIfNecessary这个方法查看
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
//注册或升级AnnotationAutoProxyCreator这个自动代理创建器
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext.getRegistry(), parserContext.extractSource(sourceElement));
进入这个方法
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("org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
//如果不一致 if(!cls.getName().equals(apcDefinition.getBeanClassName())) {
//那么获取优先级,判断使用哪个
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if(currentPriority < requiredPriority) {
//改变这个beandefinition的属性 apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
} else {
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Integer.valueOf(-2147483648));
beanDefinition.setRole(2);
//注册这个beanDefinition registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
//返回
return beanDefinition;
}
}
回到之前的代码段
//对proxy-target-class及expose-proxy属性进行处理 useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
进入该方法
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
if(sourceElement != null) {
//获取proxy-target-class属性值
boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute("proxy-target-class")).booleanValue();
if(proxyTargetClass) {
//处理该属性 AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
//获取expose-proxy属性值
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute("expose-proxy")).booleanValue();
if(exposeProxy) {
//处理该属性 AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
接下来来看一下proxy-target-class属性的处理,就是在BeanDefinition的属性中加入这个值为真,接着我们来了解一下这个属性,一般情况下在创建代理时会检查该类是否实现了接口,如果实现了接口,则采用jdk动态代理,如果没有,则采用cglib动态代理,如果把proxy-target-class设置成true,就会强制采用cglib动态代理,但是一般都是建议采用jdk的动态代理。那么来说一下jdk动态代理和cglib动态代理的区别。其实jdk动态代理我有在博客中写过,jdk动态代理采用接口的实现类来完成目标对象的代理。cglib代理是生成对象的子类来实现动态代理,性能比jdk强,但是无法对final方法进行代理。
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
if(registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition definition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
}
}
对exposeProxy属性的设置跟什么那个属性设置基本是一样的,就不多说了。来说一下exposeProxy这个属性,如果我们采用方法调用,那么这个方法就不回被增强,如果想要被增强的话,那么需要把exposeProxy设为true,然后在调用方法时需要AopContexy.currentProxy(),当这个获得的对象转化为接口再调用方法。
回到原来的方法
//注册组件并通知
registerComponentIfNecessary(beanDefinition, parserContext);
}
AnnotationAutoProxyCreatorIfNecessary类实现了BeanPostProcessor的接口,所以会在容器refresh时进行实例化,并添加到容器中,那么这是怎么进行AOP代理的呢。还记不记得在创建bean方法createBean中有这么一个方法,resolveBeforeInstantiation,这个就是来获得一个代理类的,也就是进行创建AOP代理
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Creating instance of bean '" + beanName + "'");
}
this.resolveBeanClass(mbd, beanName, new Class[0]);
try {
mbd.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var5) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", var5);
}
Object beanInstance;
try {
beanInstance = this.resolveBeforeInstantiation(beanName, mbd);
if(beanInstance != null) {
return beanInstance;
}
} catch (Throwable var6) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var6);
}
beanInstance = this.doCreateBean(beanName, mbd, args);
if(this.logger.isDebugEnabled()) {
this.logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
我们进入这个resolveBeforeInstantiation方法。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if(!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if(mbd.hasBeanClass() && !mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
bean = this.applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
if(bean != null) {
bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
mbd.beforeInstantiationResolved = Boolean.valueOf(bean != null);
}
return bean;
}
首先来看这个applyBeanPostProcessorsBeforeInstantiation方法,我们可以看出,如果BeanPostProcessor属于InstantiationAwareBeanPostProcessor,那么执行这个beanpost处理器的postProcessBeforeInstantiation方法,
AnnotationAutoProxyCreatorIfNecessary就是
InstantiationAwareBeanPostProcessor的子类,所以执行这个方法。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Iterator var3 = this.getBeanPostProcessors().iterator();
while(var3.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var3.next();
if(bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if(result != null) {
return result;
}
}
}
return null;
}
我们进入这个自动代理创建器,找到初始化前置方法,这个方法的实现是在父类AbstractAutoProxyCreator里面,
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
//根据class和beanName构建出key,结构为beanclassName_beanName
Object cacheKey = this.getCacheKey(beanClass, beanName);
//beanName为空或者没有处理过
if(beanName == null || !this.targetSourcedBeans.contains(beanName)) {
//如果不需要处理
if(this.advisedBeans.containsKey(cacheKey)) {
return null;
}
//如果不应该代理或者不需要自动代理
if(this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
if(beanName != null) {
//获得目标实例,也就是说这个需要被代理的实例对象
TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
if(targetSource != null) {
//添加记录
this.targetSourcedBeans.add(beanName);
//获取针对这个bean的增强
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
//创建代理
Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
}
return null;
}
但是走到这里时,我们会发现TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);一般没有在xml文件中配置targetsource,这个值为空。所以会返回null,那么。就需要继续创建bean,在bean实例化后,填充完属性后,又会进入initmethod方法,在这里也会对初始化的前后置处理器进行调用。然后我们来看自动代理创建类的这两个方法。
前置处理没有做任何处理
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
后置处理,我们
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if(!this.earlyProxyReferences.contains(cacheKey)) {
//如果适合代理,就需要封装指定bean
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
进入wrapIfNecessary方法,其实这个跟这个那个实例前置处理还是很像的
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//如果已经处理过
if(beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else
//如果无须增强 if(Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else
//如果是不是基础类,应该代理,而且需要自动代理
if(!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
//获取所有切点和通知
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
进入这个方法查看,这是个子类实现的方法
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
return advisors.isEmpty()?DO_NOT_PROXY:advisors.toArray();
}
进入findEligibleAdvisors方法
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//获得增强器
List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
由于我们分析的是使用注解的AOP,所以这个方法是在AnnotationAwareAspectJAutoProxyCreator中完成。
protected List<Advisor> findCandidateAdvisors() {
//在使用注解方式配置AOP的时候并不是丢弃了对XML配置的支持
//在这里调用父类的方法加载配置文件的AOP声明
List<Advisor> advisors = super.findCandidateAdvisors();
//添加获取bean注解增强的功能 advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
我们进入这个buildAspectJAdvisors方法
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = null;
synchronized(this) {
aspectNames = this.aspectBeanNames;
if(aspectNames == null) {
List<Advisor> advisors = new LinkedList();
List<String> aspectNames = new LinkedList();
//找到所有的beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
String[] var18 = beanNames;
int var19 = beanNames.length;
//遍历所有的注册的bean,找出含有AspectJ的类
for(int var7 = 0; var7 < var19; ++var7) {
String beanName = var18[var7];
if(this.isEligibleBean(beanName)) {
Class<?> beanType = this.beanFactory.getType(beanName);
//如果存在AspectJ注解
if(beanType != null && this.advisorFactory.isAspect(beanType)) {
//添加到aspect集合名中
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if(amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//获取该类中所有的增强方法
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
我们进入这个方法查看,这个方法需要自己找,这个方法为了获取所有的增强方法
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory maaif) {
//获取apectj类的class对象
Class<?> aspectClass = maaif.getAspectMetadata().getAspectClass();
//获取标记为aspectj的name
String aspectName = maaif.getAspectMetadata().getAspectName();
//验证
this.validate(aspectClass);
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(maaif);
List<Advisor> advisors = new LinkedList();
//得到所有的增强方法
Iterator var6 = this.getAdvisorMethods(aspectClass).iterator();
//遍历
while(var6.hasNext()) {
Method method = (Method)var6.next();
//获取Advisor,在这个方法内会把增强方法,跟切点装配到一块,忽略piontcut
Advisor advisor = this.getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
我们看一下getAdvisor这个方法,看一下怎么获取的增强器
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {
this.validate(aif.getAspectMetadata().getAspectClass());
//获取切点
AspectJExpressionPointcut ajexp = this.getPointcut(candidateAdviceMethod, aif.getAspectMetadata().getAspectClass());
看一下如何获取的切点
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
//获取方法上的注解
AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if(aspectJAnnotation == null) {
return null;
} else {
//封装增强方法
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class[0]);
//提取注解中的表达式 ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
return ajexp;
}
}
返回之前的方法
//根据切点信息生成增强器
return ajexp == null?null:new InstantiationModelAwarePointcutAdvisorImpl(this, ajexp, aif, candidateAdviceMethod, declarationOrderInAspect, aspectName);
}
进入InstantiationModelAwarePointcutAdvisorImpl构造方法
public InstantiationModelAwarePointcutAdvisorImpl(AspectJAdvisorFactory af, AspectJExpressionPointcut ajexp, MetadataAwareAspectInstanceFactory aif, Method method, int declarationOrderInAspect, String aspectName) {
//对下面属性进行封装
this.declaredPointcut = ajexp;
this.method = method;
this.atAspectJAdvisorFactory = af;
this.aspectInstanceFactory = aif;
this.declarationOrder = declarationOrderInAspect;
this.aspectName = aspectName;
//如果不是懒加载
if(aif.getAspectMetadata().isLazilyInstantiated()) {
Pointcut preInstantiationPointcut = Pointcuts.union(aif.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
this.pointcut = new InstantiationModelAwarePointcutAdvisorImpl.PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aif, (InstantiationModelAwarePointcutAdvisorImpl.SyntheticClass_1)null);
this.lazy = true;
} else {
//生成不同的增强器
this.instantiatedAdvice = this.instantiateAdvice(this.declaredPointcut);
this.pointcut = this.declaredPointcut;
this.lazy = false;
}
}
进入instantiateAdvice方法
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
return this.atAspectJAdvisorFactory.getAdvice(this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
}
找到这个getAdvice代码
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut ajexp, MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {
Class<?> candidateAspectClass = aif.getAspectMetadata().getAspectClass();
this.validate(candidateAspectClass);
AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if(aspectJAnnotation == null) {
return null;
} else if(!this.isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: Offending method '" + candidateAdviceMethod + "' in class [" + candidateAspectClass.getName() + "]");
} else {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
Object springAdvice;
//根据不同的类型封装不同的增强器 switch(ReflectiveAspectJAdvisorFactory.SyntheticClass_1.$SwitchMap$org$springframework$aop$aspectj$annotation$AbstractAspectJAdvisorFactory$AspectJAnnotationType[aspectJAnnotation.getAnnotationType().ordinal()]) {
case 1:
springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, ajexp, aif);
break;
case 2:
springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, ajexp, aif);
break;
case 3:
springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, ajexp, aif);
AfterReturning afterReturningAnnotation = (AfterReturning)aspectJAnnotation.getAnnotation();
if(StringUtils.hasText(afterReturningAnnotation.returning())) {
((AbstractAspectJAdvice)springAdvice).setReturningName(afterReturningAnnotation.returning());
}
break;
case 4:
springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, ajexp, aif);
AfterThrowing afterThrowingAnnotation = (AfterThrowing)aspectJAnnotation.getAnnotation();
if(StringUtils.hasText(afterThrowingAnnotation.throwing())) {
((AbstractAspectJAdvice)springAdvice).setThrowingName(afterThrowingAnnotation.throwing());
}
break;
case 5:
springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, ajexp, aif);
break;
case 6:
if(this.logger.isDebugEnabled()) {
this.logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
default:
throw new UnsupportedOperationException("Unsupported advice type on method " + candidateAdviceMethod);
}
((AbstractAspectJAdvice)springAdvice).setAspectName(aspectName);
((AbstractAspectJAdvice)springAdvice).setDeclarationOrder(declarationOrderInAspect);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if(argNames != null) {
((AbstractAspectJAdvice)springAdvice).setArgumentNamesFromStringArray(argNames);
}
((AbstractAspectJAdvice)springAdvice).calculateArgumentBindings();
return (Advice)springAdvice;
}
}
返回原来代码
if(advisor != null) {
//添加到集合中
advisors.add(advisor);
}
}
if(!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
//如果寻找的增强器不为空,又配置了增强延迟初始化那么需要在收尾加入同步实例化增强器
Advisor instantiationAdvisor = new ReflectiveAspectJAdvisorFactory.SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
Field[] var12 = aspectClass.getDeclaredFields();
int var13 = var12.length;
//获取DeclareParents注解
for(int var14 = 0; var14 < var13; ++var14) {
Field field = var12[var14];
Advisor advisor = this.getDeclareParentsAdvisor(field);
if(advisor != null) {
advisors.add(advisor);
}
}
//返回所有的增强
return advisors;
}
返回之前的方法,这时候已经获取了增强方法。
if(this.beanFactory.isSingleton(beanName)) {
//如果是单例,就放进缓存中 this.advisorsCache.put(beanName, classAdvisors);
} else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
} else {
if(this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
if(aspectNames.isEmpty()) {
return Collections.emptyList();
} else {
//记录到缓存中
List<Advisor> advisors = new LinkedList();
Iterator var3 = aspectNames.iterator();
while(var3.hasNext()) {
String aspectName = (String)var3.next();
List<Advisor> cachedAdvisors = (List)this.advisorsCache.get(aspectName);
if(cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
} else {
MetadataAwareAspectInstanceFactory factory = (MetadataAwareAspectInstanceFactory)this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
}
得到所有的增强后,则需要找到匹配的增强器
//寻找配置的增强器
List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
this.extendAdvisors(eligibleAdvisors);
if(!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
我们来查看这个这个findAdvisorsThatCanApply方法
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
List var4;
try {
//过滤
var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
ProxyCreationContext.setCurrentProxiedBeanName((String)null);
}
return var4;
}
进入findAdvisorsThatCanApply方法
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if(candidateAdvisors.isEmpty()) {
return candidateAdvisors;
} else {
List<Advisor> eligibleAdvisors = new LinkedList();
Iterator var3 = candidateAdvisors.iterator();
while(var3.hasNext()) {
Advisor candidate = (Advisor)var3.next();
//首先处理引介增强,在这里就在进行匹配了,先会获取piontcut的execution表达式,然后和该类中的所有方法进行匹配,留下适合的增强器。
if(candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
Iterator var7 = candidateAdvisors.iterator();
while(var7.hasNext()) {
Advisor candidate = (Advisor)var7.next();
//对于普通bean的处理
if(!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
}
获取增强器后,那么就要进行代理的创建了。
if(specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
我们来看一下如何创建代理
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
//获取代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
//获取当前类相关属性
proxyFactory.copyFrom(this);
if(!proxyFactory.isProxyTargetClass()) {
//决定对于给定的bean是否应该使用targetClass而不是他的接口代理,检查proxtTargetClass设置以及preserveTargetClass属性,也就是说,在这里已经开始选择了代理是采用jdk还是cglib
if(this.shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
//添加代理接口
this.evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//将拦截器封装为增强器
Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
我们来看看这个方法
protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
Advisor[] commonInterceptors = this.resolveInterceptorNames();
List<Object> allInterceptors = new ArrayList();
if(specificInterceptors != null) {
//加入拦截器 allInterceptors.addAll(Arrays.asList(specificInterceptors));
if(commonInterceptors != null) {
if(this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
} else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
int i;
if(this.logger.isDebugEnabled()) {
int nrOfCommonInterceptors = commonInterceptors != null?commonInterceptors.length:0;
i = specificInterceptors != null?specificInterceptors.length:0;
this.logger.debug("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors + " common interceptors and " + i + " specific interceptors");
}
Advisor[] advisors = new Advisor[allInterceptors.size()];
for(i = 0; i < allInterceptors.size(); ++i) {
//将拦截器封装为Advisor
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}
来看一下wrap这个方法
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if(adviceObject instanceof Advisor) {
//如果是Advisor类就直接返回
return (Advisor)adviceObject;
} else if(!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
} else {
Advice advice = (Advice)adviceObject;
if(advice instanceof MethodInterceptor) {
//如果是方法拦截器就生成默认的Advisor
return new DefaultPointcutAdvisor(advice);
} else {
Iterator var3 = this.adapters.iterator();
//如果存在适配器就进行封装
AdvisorAdapter adapter;
do {
if(!var3.hasNext()) {
throw new UnknownAdviceTypeException(advice);
}
adapter = (AdvisorAdapter)var3.next();
} while(!adapter.supportsAdvice(advice));
return new DefaultPointcutAdvisor(advice);
}
}
}
Advisor[] var7 = advisors;
int var8 = advisors.length;
//往代理工厂里加入所有增强器
for(int var9 = 0; var9 < var8; ++var9) {
Advisor advisor = var7[var9];
proxyFactory.addAdvisor(advisor);
}
//设置需要代理的类
proxyFactory.setTargetSource(targetSource);
//定制代理
this.customizeProxyFactory(proxyFactory);
//用来控制代理工厂被配置之后,是否允许修改通知
//缺省值为false(即在代理被配置后不允许修改代理)
proxyFactory.setFrozen(this.freezeProxy);
if(this.advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//得到代理
return proxyFactory.getProxy(this.proxyClassLoader);
}
我们来看一下getProxy方法
public Object getProxy(ClassLoader classLoader) {
return this.createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
if(!this.active) {
this.activate();
}
//创建代理
return this.getAopProxyFactory().createAopProxy(this);
}
//在这里会选择用cglib做动态代理还是jdk
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if(!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
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.");
} else {
return (AopProxy)(targetClass.isInterface()?new JdkDynamicAopProxy(config):new ObjenesisCglibAopProxy(config));
}
}
}
我们来看一下jdk动态代理怎么完成的aop,在之前的博客中已经讲过了简单的jdk动态代理,通过接口生成一个代理类,代理类调用InvocatioHandler的inovke方法,来完成代理。我们来看一下JdkDynamicAopProxy这个类。
看一个获取代理方法
public Object getProxy(ClassLoader classLoader) {
if(logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
可见跟jdk的动态代理十分相似,主要还是在于这个类的inovke方法。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class<?> targetClass = null;
Object target = null;
Object retVal;
try {
//equals方法的处理
if(!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
Boolean var18 = Boolean.valueOf(this.equals(args[0]));
return var18;
}
//hash方法的处理
if(!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
Integer var17 = Integer.valueOf(this.hashCode());
return var17;
}
if(this.advised.opaque || !method.getDeclaringClass().isInterface() || !method.getDeclaringClass().isAssignableFrom(Advised.class)) {
if(this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
if(target != null) {
targetClass = target.getClass();
}
//获取对应方法的拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
//如果拦截器是空的,直接执行该方法
if(chain.isEmpty()) {
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
} else {
//将方法和拦截器封装在ReflectiveMethodInvocation中
MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//执行拦截器
retVal = invocation.proceed();
}
Class<?> returnType = method.getReturnType();
if(retVal != null && retVal == target && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
} else if(retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
}
Object var13 = retVal;
return var13;
}
retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
} finally {
if(target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if(setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
return retVal;
}
我们来看一下这个proceed的执行过程
public Object proceed() throws Throwable {
//如果执行完所有增强后的执行切点方法
if(this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return this.invokeJoinpoint();
} else {
//获取下一个要执行的拦截器
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if(interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
return dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)?dm.interceptor.invoke(this):this.proceed();
} else {
//如果是普通拦截器就是调用inoke方法
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
}
}
了解过设计模式的应该知道这叫责任链模式。
所以前置增强的执行过程是先调用增强方法,在调用这个process,相当于责任的传递,而后置增强是先调用这个process,然后return,最后用finally执行后置方法。
除了AOP动态代理,还有静态代理,静态代理是在生成class时,虚拟机直接生成了代理后的class。