在分析Aop源码之前最好先回顾下Aop相关知识点:https://blog.csdn.net/qq_23536449/article/details/96868578和实现Aop三种方式:https://blog.csdn.net/qq_23536449/article/details/96899712,Aop之DeclareParents使用https://blog.csdn.net/qq_23536449/article/details/97008737
1.在https://blog.csdn.net/qq_23536449/article/details/95071632文中提到了对自定义标签元素是如何实现的,有兴趣可以回顾下。实现Aop的关键肯定少不了对标签元素的解析,我们直接找到AopNameSpaceHandler类
2.ConfigBeanDefinitionParser.parse方法;
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
//创建CompositeComponentDefinition对象
CompositeComponentDefinition compositeDef =
new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compositeDef);
//注册或配置一个auto-proxy creator的beanDefinition
configureAutoProxyCreator(parserContext, element);
//获取aop:config元素的子element
List<Element> childElts = DomUtils.getChildElements(element);
for (Element elt: childElts) {
String localName = parserContext.getDelegate().getLocalName(elt);
//解析pointcut
if (POINTCUT.equals(localName)) {
parsePointcut(elt, parserContext);
}
//解析advisor
else if (ADVISOR.equals(localName)) {
parseAdvisor(elt, parserContext);
}
//解析aspect元素
else if (ASPECT.equals(localName)) {
parseAspect(elt, parserContext);
}
}
parserContext.popAndRegisterContainingComponent();
return null;
}
主要做了两件事情
- a.注册或者配置一个auto-proxy creator的bean definition
- b.解析标签元素aop:point aop:advisor aop:aspect
2.先来先来关注下configureAutoProxyCreator(parserContext, element);
/**
* 配置支持'{@code <aop:config/>}'标签的auto-proxy creator的beanDefinition
* @see AopNamespaceUtils
*/
private void configureAutoProxyCreator(ParserContext parserContext, Element element) {
AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
}
根据名称不难理解其实这里是根据需要注册AspectJAutoProxyCreator beanDefinition;然后我想说的是其实解析aspect-autoproxy标签的 AspectJAutoProxyBeanDefinitionParser也是做了同样的事情,不过他注册的是更NB的AnnotationAwareAspectJAutoProxyCreator.class,在AspectJAutoProxyCreator上扩展了对@AspectJ注解实现AOP的支持。所以下文我们分析auto-proxy creator时分析更NB的AnnotationAwareAspectJAutoProxyCreator.java。
public static void registerAspectJAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
//注册AspectJAwareAdvisorAutoProxyCreator.class的beanDefinition
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
//配置的proxy-target-class属性和expose-proxy属性的读取
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
//注册一个组件bean到parserContext的CompositeComponentDefinition中
registerComponentIfNecessary(beanDefinition, parserContext);
}
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
if (sourceElement != null) {
//获取proxy-target-class属性
//如果proxy-target-class 属性值被设置为true,那么基于类的代理将起作用(这时需要cglib库)。
// 如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理将起作用
//但是,即使设置为false,如果目标类没有生命接口,
boolean proxyTargetClass = Boolean.parseBoolean(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
//获取到auto-proxy creator对应的BeanDefinition
//并且设置proxy-target-class属性值
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
//获取expose-proxy属性
//exposeProxy用来标记是否允许将代理对象以ThreadLocal的形式暴露给aop框架,以便通过AopContext对代理对象进行重复利用
boolean exposeProxy = Boolean.parseBoolean(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
private static void registerComponentIfNecessary(BeanDefinition beanDefinition, ParserContext parserContext) {
if (beanDefinition != null) {
parserContext.registerComponent(
new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME));
}
}
这里是使用aop:config帮我们注册的auto-proxy creator的代码
public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);
}
当我们使用aop:aspect-autoproxy时注册的auto-proxy creator是这样子的
/**
* 如果有必要的话注册AspectJAnnotationAutoProxyCreator
* @param registry
* @param source
* @return
*/
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
//注册或者升级AspectJAnnotationAutoProxyCreator
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
然后下面就是看看用户有没有配置了auto-proxy creator,并且根据优先级选择最NB的创建他的BeanDefinition注册到beanDefinitionRegistry;用于帮我们后面创建代理。
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//包含org.springframework.aop.config.internalAutoProxyCreator,可能是自己配置的
//这时候我们需要根据优先级确定要使用的auto-proxy creator
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
//获取internalAutoProxyCreator的beandefinition
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
//判断和传递过来的bean的className不一致
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
// beanDefinition中定义的internalAutoProxyCreator的优先级
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
// 我们所需要的auto-proxy creator的优先级
int requiredPriority = findPriorityForClass(cls);
// 如果我们需求的auto-proxy creator的优先级高,则使用我们需要的
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
//如果已经存在了并且与将要创建的一样直接返回
return null;
}
//创建auto-proxy creator的beanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
//在普通属性中添加order属性 order 并且值代表最高优先级
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
//设置bean的角色为内部
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//注册beandefinition
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
3.解析aop:pointcut;解析切入点beanDefinition然后注册到beanDefinitionRegistry
首先我们来看下Spring中对pointcut的抽象
- Pointcut:Spring的核心pointcut抽象类;一个切点是一个{@link ClassFilter}和一个{@link MethodMatcher}的组合
- ExpressionPointcut:由使用String表达式的pointcut实现的接口,扩展了expression的支持
- AbstractExpressionPointcut:表达式pointcut的抽象超类,提供location和expression属性
- ClassFilter:从给出的一系列目标目标classes过滤出符合的pointcut或者introduction;方法有matches(Class<?> clzz)切入点是否应用于给定的接口或目标类
- MethodMatcher:{@link Pointcut}的一部分:检查目标方法是否符合advice的条件
- IntroductionAwareMethodMatcher:一种特殊类型的{@link MethodMatcher},在匹配方法时会考虑intructions例如,如果没有introductions在目标类上,方法匹配器可能能够更有效地优化匹配
- AspectJExpressionPointcut: Spring {@link org.springframework.aop.Pointcut}实现使用AspectJ编织器来评估切入点表达式,切入点表达式值是AspectJ表达式。 这个可以引用其他切入点并使用合成和其他操作
解析过程
/**
* 解析类似<aop:pointcut expression="execution(* *.aspectTest(..))" id="p1"/>
* 并注册BeanDefinition到BeanDefinitionRegistry
*
*/
private AbstractBeanDefinition parsePointcut(Element pointcutElement, ParserContext parserContext) {
//id属性
String id = pointcutElement.getAttribute(ID);
//expression属性
String expression = pointcutElement.getAttribute(EXPRESSION);
AbstractBeanDefinition pointcutDefinition = null;
try {
this.parseState.push(new PointcutEntry(id));
//创建AspectJExpressionPointcut.class的beanDefinition
pointcutDefinition = createPointcutDefinition(expression);
pointcutDefinition.setSource(parserContext.extractSource(pointcutElement));
//切点bean名称赋值为id
String pointcutBeanName = id;
if (StringUtils.hasText(pointcutBeanName)) {
parserContext.getRegistry().registerBeanDefinition(pointcutBeanName, pointcutDefinition);
}
else {
//没有bean名称生成一个注册到beanDefinitonRegistry
pointcutBeanName = parserContext.getReaderContext().registerWithGeneratedName(pointcutDefinition);
}
//注册PointcutComponentDefinition到readerContext的containingComponent并通知监听器
parserContext.registerComponent(
new PointcutComponentDefinition(pointcutBeanName, pointcutDefinition, expression));
}
finally {
this.parseState.pop();
}
return pointcutDefinition;
}
/**
* 使用给定的pointcut表达式创建一个{@link AspectJExpressionPointcut}的beanDefinition
*
*/
protected AbstractBeanDefinition createPointcutDefinition(String expression) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(AspectJExpressionPointcut.class);
beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
beanDefinition.setSynthetic(true);
beanDefinition.getPropertyValues().add(EXPRESSION, expression);
return beanDefinition;
}
4.解析aop:advisor标签;一个advisor元素中的配置可能对应多个增强比如MethodBeforeAdvice,AfterAdvcice,AfterReturnningAdvice
Spring对它的抽象
- Advisor:持有AOP advice(增强,在连接点要执行的动作可以理解为补充逻辑)以及确定advice适用性的过滤器(例如切入点)的基本接口, <i>此接口不供Spring用户使用,但允许支持不同类型的advices。springAOP是符合AOP Alliance拦截api规范的,并且通过方法拦截, 这个接口支持不同使用interception类型的advice(增强),比如<b>before</b> and <b>after</b>
- PointcutAdvisor:由pointcut驱动的所有Advisors的超级接口。方法getPointcut()返回当前advisor驱动的pointcut
- AbstractPointcutAdvisor:{@link org.springframework.aop.PointcutAdvisor}实现的抽象基类。 可以为子类返回特定的pointcut/advisor或可自由配置的pointcut/advisor
- AbstractBeanFactoryPointcutAdvisor:基于BeanFactory的抽象PointcutAdvisor, 允许将任何advice配置为对BeanFactory中的Advice bean的引用,如果在BeanFactory中运行)在初始化时增加松散耦合指定advice的beanName而不是advice自身对象为了在切入点实际匹配之前不初始化通知对象
- DefaultBeanFactoryPointcutAdvisor:允许将任何增强配置为对BeanFactory中的Advice bean的引用并且基于BeaFactory具体的PointcutAdvisor, 通过使用beanFactory配置pointCut属性。
解析过程
/**
* 解析类似<aop:advisor advice-ref="explictAdvisor" pointcut-ref="p1" id="ea"/>
* 并使用提供的{@link BeanDefinitionRegistry}注册生成的{@link org.springframework.aop.Advisor}
* 和任何生成的{@link org.springframework.aop.Pointcut}。
*
*/
private void parseAdvisor(Element advisorElement, ParserContext parserContext) {
AbstractBeanDefinition advisorDef = createAdvisorBeanDefinition(advisorElement, parserContext);
//解析id属性
String id = advisorElement.getAttribute(ID);
try {
this.parseState.push(new AdvisorEntry(id));
//advisorBeanName 赋值
String advisorBeanName = id;
if (StringUtils.hasText(advisorBeanName)) {
parserContext.getRegistry().registerBeanDefinition(advisorBeanName, advisorDef);
}
//为advisorbean生成一个名称并注册bean
else {
advisorBeanName = parserContext.getReaderContext().registerWithGeneratedName(advisorDef);
}
//解析advisor标签元素的pointcut属性
Object pointcut = parsePointcutProperty(advisorElement, parserContext);
if (pointcut instanceof BeanDefinition) {
advisorDef.getPropertyValues().add(POINTCUT, pointcut);
//注册AdvisorComponentDefinition到readerContext的containingComponent并通知监听器
parserContext.registerComponent(
new AdvisorComponentDefinition(advisorBeanName, advisorDef, (BeanDefinition) pointcut));
}
else if (pointcut instanceof String) {
//注册AdvisorComponentDefinition到readerContext的containingComponent并通知监听器
advisorDef.getPropertyValues().add(POINTCUT, new RuntimeBeanReference((String) pointcut));
parserContext.registerComponent(
new AdvisorComponentDefinition(advisorBeanName, advisorDef));
}
}
finally {
this.parseState.pop();
}
}
/**
* 为给定的advisor的xml描述创建一个{@link RootBeanDefinition},不解析'{@code pointcut}' or '{@code pointcut-ref}'
*/
private AbstractBeanDefinition createAdvisorBeanDefinition(Element advisorElement, ParserContext parserContext) {
//创建DefaultBeanFactoryPointcutAdvisor.class的bean definition
RootBeanDefinition advisorDefinition = new RootBeanDefinition(DefaultBeanFactoryPointcutAdvisor.class);
advisorDefinition.setSource(parserContext.extractSource(advisorElement));
//advice-ref属性
String adviceRef = advisorElement.getAttribute(ADVICE_REF);
//没有指定增强类 报错
if (!StringUtils.hasText(adviceRef)) {
parserContext.getReaderContext().error(
"'advice-ref' attribute contains empty value.", advisorElement, this.parseState.snapshot());
}
else {
//添加adviceBeanName属性,类型为RuntimeBeanNameReference
advisorDefinition.getPropertyValues().add(
ADVICE_BEAN_NAME, new RuntimeBeanNameReference(adviceRef));
}
//如果有order属性,添加到beanDefinition
if (advisorElement.hasAttribute(ORDER_PROPERTY)) {
advisorDefinition.getPropertyValues().add(
ORDER_PROPERTY, advisorElement.getAttribute(ORDER_PROPERTY));
}
return advisorDefinition;
}
/**
*
* 解析所提供的{@link Element}的{@code pointcut}或{@code pointcut-ref}属性,并根据需要添加{@code pointcut}属性
* 如有必要,为切入点生成{@link org.springframework.beans.factory.config.BeanDefinition}并返回其bean名称,
* 否则返回引用切入点的bean名称
*/
private Object parsePointcutProperty(Element element, ParserContext parserContext) {
//pointcut 和pointcut-ref属性都有 报错
if (element.hasAttribute(POINTCUT) && element.hasAttribute(POINTCUT_REF)) {
parserContext.getReaderContext().error(
"Cannot define both 'pointcut' and 'pointcut-ref' on <advisor> tag.",
element, this.parseState.snapshot());
return null;
}
//包含pointcut属性,
else if (element.hasAttribute(POINTCUT)) {
// 解析并创建AspectJExpressionPointcut类型的beanDefinition
String expression = element.getAttribute(POINTCUT);
AbstractBeanDefinition pointcutDefinition = createPointcutDefinition(expression);
pointcutDefinition.setSource(parserContext.extractSource(element));
return pointcutDefinition;
}
//包含的是pointcut-ref属性
else if (element.hasAttribute(POINTCUT_REF)) {
String pointcutRef = element.getAttribute(POINTCUT_REF);
//属性值为空,抛出异常
if (!StringUtils.hasText(pointcutRef)) {
parserContext.getReaderContext().error(
"'pointcut-ref' attribute contains empty value.", element, this.parseState.snapshot());
return null;
}
return pointcutRef;
}
else {
parserContext.getReaderContext().error(
"Must define one of 'pointcut' or 'pointcut-ref' on <advisor> tag.",
element, this.parseState.snapshot());
return null;
}
}
不难理解advisor包含两部分,一部分是pointcut解析另外一部分就是advice的解析。
5.解析aop:aspect标签元素;aspect标签元素分为两部分解析aop:before,aop:after,aop:around等类似标签元素,还有一部分是aop:declare-parents关于他的用法我们在文章开头已经提到过了
我们先看前半部分的解析即解析aop:declare-parents
关于declare-parents的抽象
IntroductionInfo:提供描述一个introduction必须信息的接口,他有一个方法即:getInterfaces()返回此Advisor或Advice引入的其他接口
IntroductionAdvisor:更多AOP行为的advisors的超类 ;接口不能直接实现; 子接口必须提供introduction的增强类型实现 ;给目标添加未实现接口的AOP增强
DeclareParentsAdvisor:委托给给定对象的Intruction的advisor,可以在AspectJ注解内部通过@DeclareParents实现增强行为
代码解析部分
private void parseAspect(Element aspectElement, ParserContext parserContext) {
//解析Id
String aspectId = aspectElement.getAttribute(ID);
//解析ref
String aspectName = aspectElement.getAttribute(REF);
try {
this.parseState.push(new AspectEntry(aspectId, aspectName));
List<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>();
List<BeanReference> beanReferences = new ArrayList<BeanReference>();
//解析这种标签元素
/**
* <aop:declare-parents implement-interface="org.springframework.study.day13.IDeclareParent"
* types-matching="org.springframework.study.day13.NoMethodAspectBean"
* default-impl="org.springframework.study.day13.IDeclareParentImpl"/>
*/
List<Element> declareParents = DomUtils.getChildElementsByTagName(aspectElement, DECLARE_PARENTS);
for (int i = METHOD_INDEX; i < declareParents.size(); i++) {
Element declareParentsElement = declareParents.get(i);
beanDefinitions.add(parseDeclareParents(declareParentsElement, parserContext));
}
/**
* 解析'{@code declare-parents}'元素并使用封装在提供的ParserContext中的BeanDefinitionRegistry
* 注册相应的DeclareParentsAdvisor。
*/
private AbstractBeanDefinition parseDeclareParents(Element declareParentsElement, ParserContext parserContext) {
//使用BeanDefinition的建造器解析declare-parents元素
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DeclareParentsAdvisor.class);
//implement-interface属性
builder.addConstructorArgValue(declareParentsElement.getAttribute(IMPLEMENT_INTERFACE));
//types-matching属性
builder.addConstructorArgValue(declareParentsElement.getAttribute(TYPE_PATTERN));
//default-impl属性
String defaultImpl = declareParentsElement.getAttribute(DEFAULT_IMPL);
//delegate-ref属性
String delegateRef = declareParentsElement.getAttribute(DELEGATE_REF);
//default-impl属性和delegate-ref只需要配置一个
if (StringUtils.hasText(defaultImpl) && !StringUtils.hasText(delegateRef)) {
builder.addConstructorArgValue(defaultImpl);
}
else if (StringUtils.hasText(delegateRef) && !StringUtils.hasText(defaultImpl)) {
builder.addConstructorArgReference(delegateRef);
}
else {
parserContext.getReaderContext().error(
"Exactly one of the " + DEFAULT_IMPL + " or " + DELEGATE_REF + " attributes must be specified",
declareParentsElement, this.parseState.snapshot());
}
AbstractBeanDefinition definition = builder.getBeanDefinition();
definition.setSource(parserContext.extractSource(declareParentsElement));
//使用生成的beanName注册beanDefinition
parserContext.getReaderContext().registerWithGeneratedName(definition);
return definition;
}
然后是解析advice元素;aop:before,aop:after,aop:around等类似标签元素,对于每个元素的增强,Spring将他们封装为AspectJPointcutAdvisor对象
AspectJPointcutAdvisor:适配{@link AbstractAspectJAdvice}到{@link org.springframework.aop.PointcutAdvisor} 接口的类,其属性包括切入点和AbstractAspectJadvice属性
/**
* 解析'{@code before}', '{@code after}', '{@code after-returning}',
* '{@code after-throwing}' or '{@code around}'并且注册beanDefinition
* 到给定的BeanDefinitionRegistry
* @return the generated advice RootBeanDefinition
*/
private AbstractBeanDefinition parseAdvice(
String aspectName, int order, Element aspectElement, Element adviceElement, ParserContext parserContext,
List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {
try {
this.parseState.push(new AdviceEntry(parserContext.getDelegate().getLocalName(adviceElement)));
//创建一个MethodFactoryBean的definition
RootBeanDefinition methodDefinition = new RootBeanDefinition(MethodLocatingFactoryBean.class);
//设置几个属性
methodDefinition.getPropertyValues().add("targetBeanName", aspectName);
methodDefinition.getPropertyValues().add("methodName", adviceElement.getAttribute("method"));
methodDefinition.setSynthetic(true);
//这个beanDefinition用于生产aspectName对应的bean
RootBeanDefinition aspectFactoryDef =
new RootBeanDefinition(SimpleBeanFactoryAwareAspectInstanceFactory.class);
aspectFactoryDef.getPropertyValues().add("aspectBeanName", aspectName);
aspectFactoryDef.setSynthetic(true);
// register the pointcut
//注册pointcut
AbstractBeanDefinition adviceDef = createAdviceDefinition(
adviceElement, parserContext, aspectName, order, methodDefinition, aspectFactoryDef,
beanDefinitions, beanReferences);
// configure the advisor
// 创建AspectJPointcutAdvisor的定义并配置
RootBeanDefinition advisorDefinition = new RootBeanDefinition(AspectJPointcutAdvisor.class);
advisorDefinition.setSource(parserContext.extractSource(adviceElement));
advisorDefinition.getConstructorArgumentValues().addGenericArgumentValue(adviceDef);
if (aspectElement.hasAttribute(ORDER_PROPERTY)) {
advisorDefinition.getPropertyValues().add(
ORDER_PROPERTY, aspectElement.getAttribute(ORDER_PROPERTY));
}
// 注册advisor定义
parserContext.getReaderContext().registerWithGeneratedName(advisorDefinition);
return advisorDefinition;
}
finally {
this.parseState.pop();
}
}
/**
* Creates the RootBeanDefinition for a POJO advice bean. Also causes pointcut
* parsing to occur so that the pointcut may be associate with the advice bean.
* This same pointcut is also configured as the pointcut for the enclosing
* Advisor definition using the supplied MutablePropertyValues.
*
* 为advice bean创建RootBeanDefinition。这会导致解析pointcut并且与advice bean相关联.
* 同样的切入点也被配置为使用提供的MutablePropertyValues封闭Advisor定义的pointcut
*/
private AbstractBeanDefinition createAdviceDefinition(
Element adviceElement, ParserContext parserContext, String aspectName, int order,
RootBeanDefinition methodDef, RootBeanDefinition aspectFactoryDef,
List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {
//创建advice的beanDefinitoin
RootBeanDefinition adviceDefinition = new RootBeanDefinition(getAdviceClass(adviceElement, parserContext));
adviceDefinition.setSource(parserContext.extractSource(adviceElement));
//设置相关属性
adviceDefinition.getPropertyValues().add(ASPECT_NAME_PROPERTY, aspectName);
adviceDefinition.getPropertyValues().add(DECLARATION_ORDER_PROPERTY, order);
//包含returning属性
if (adviceElement.hasAttribute(RETURNING)) {
adviceDefinition.getPropertyValues().add(
RETURNING_PROPERTY, adviceElement.getAttribute(RETURNING));
}
//包含throwing属性
if (adviceElement.hasAttribute(THROWING)) {
adviceDefinition.getPropertyValues().add(
THROWING_PROPERTY, adviceElement.getAttribute(THROWING));
}
//arg-names属性
if (adviceElement.hasAttribute(ARG_NAMES)) {
adviceDefinition.getPropertyValues().add(
ARG_NAMES_PROPERTY, adviceElement.getAttribute(ARG_NAMES));
}
//各类Advice的构造函数赋值谢谢
ConstructorArgumentValues cav = adviceDefinition.getConstructorArgumentValues();
cav.addIndexedArgumentValue(METHOD_INDEX, methodDef);
Object pointcut = parsePointcutProperty(adviceElement, parserContext);
if (pointcut instanceof BeanDefinition) {
cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcut);
beanDefinitions.add((BeanDefinition) pointcut);
}
else if (pointcut instanceof String) {
RuntimeBeanReference pointcutRef = new RuntimeBeanReference((String) pointcut);
cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcutRef);
beanReferences.add(pointcutRef);
}
cav.addIndexedArgumentValue(ASPECT_INSTANCE_FACTORY_INDEX, aspectFactoryDef);
return adviceDefinition;
}
- a.该增强是那个bean的某个方法实现的MethodLocatingFactoryBean.class的beanDefinition
- b.该增强bean的工厂创建类SimpleBeanFactoryAwareAspectInstanceFactory
- c.根据a、b两步骤创建advice标签元素aop:before,aop:after,aop:around等类似标签元素对应的advice的beanDefinition如AspectJMethodBeforeAdvice、AspectJAfterReturningAdvice、AspectJAfterAdvice的beanDefinition
- d.将advice适配为AspectJPointcutAdvisor类型的beanDefinition