1.实现aop用配置文件的方式配置如下:
<bean id="logUtil" class="com.mashibing.aop.xml.util.LogUtil" ></bean><bean id="myCalculator" class="com.mashibing.aop.xml.service.MyCalculator" ></bean><aop:config><aop:aspect ref="logUtil"><aop:pointcut id="myPoint" expression="execution( Integer com.mashibing.aop.xml.service.MyCalculator.* (..))"/><aop:around method="around" pointcut-ref="myPoint"></aop:around><aop:before method="start" pointcut-ref="myPoint"></aop:before><aop:after method="logFinally" pointcut-ref="myPoint"></aop:after><aop:after-returning method="stop" pointcut-ref="myPoint" returning="result"></aop:after-returning><aop:after-throwing method="logException" pointcut-ref="myPoint" throwing="e"></aop:after-throwing></aop:aspect></aop:config><aop:aspectj-autoproxy></aop:aspectj-autoproxy>
2.接下来开始配置文件标签的解析:
真正解析关键在这个方法里
parse:108, ConfigBeanDefinitionParser (org.springframework.aop.config)@Override@Nullablepublic BeanDefinition parse(Element element, ParserContext parserContext) {CompositeComponentDefinition compositeDef =new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));parserContext.pushContainingComponent(compositeDef);// 注册自动代理模式创建器,AspectjAwareAdvisorAutoProxyCreator configureAutoProxyCreator(parserContext, element);// 解析aop:config子节点下的aop:pointcut/aop:advice/aop:aspectList<Element> childElts = DomUtils.getChildElements(element);for (Element elt: childElts) {String localName = parserContext.getDelegate().getLocalName(elt);if (POINTCUT.equals(localName)) {parsePointcut(elt, parserContext);}else if (ADVISOR.equals(localName)) {parseAdvisor(elt, parserContext);}else if (ASPECT.equals(localName)) {parseAspect(elt, parserContext);}}parserContext.popAndRegisterContainingComponent();return null;}
configureAutoProxyCreator(parserContext, element);
方法最终执行到registerOrEscalateApcAsRequired:145, AopConfigUtils (org.springframework.aop.config)
执行registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
创建AUTO_PROXY_CREATOR_BEAN_NAME的RootBeanDefinition即这个内部类的bean定义信息加载,后续创建对象org.springframework.aop.config.internalAutoProxyCreator
解析aop:config子节点下的aop:pointcut/aop:advice/aop:aspect
整个方法的调用执行链路
parseAspect(elt, parserContext);
这个方法用来解析xml配置文件,生成bean定义信息,方便后续的实例化初始化创建代理对象的操作。advisor内部有advice,创建advice内部有三个属性。
对xml文件解析为bean定义信息之后beanMap里新增如下:
对xml文件解析为bean定义信息之后开始实例化,链路如下:
给BeanPostProcessors一个机会来返回代理来替代真正的实例,应用实例化前的前置处理器,用户自定义动态代理的方式,针对于当前的被代理类需要经过标准的代理流程来创建对象
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
实例化的前置处理
postProcessBeforeInstantiation:262, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
isInfrastructureClass:判断bean的类型是不是内部的类型,
比如Advice,Pointcut,Advisor,AopInfrastructureBean这些是跟AOP相关的,所以不应该被处理
shouldSkip:是否跳过
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName))
findAdvisorBeans:81,BeanFactoryAdvisorRetrievalHelper(org.springframework.aop.framework.autoproxy)
这个方法获取当前BeanFactory中所有实现了Advisor接口的bean的名称然后进行实例化生成bean对象放到缓存中
从spring中获取 bean class 对应的 bean,将其放入advisors中:org.springframework.aop.aspectj.AspectJPointcutAdvisor#0
advisors.add(this.beanFactory.getBean(name, Advisor.class));
这个方法实例化生成advisor,前面说过advisor有advice,advice有三个对象,因此要先生成advice需要的三个对象,advisor属性constructorArgumentValues可以看到有
Root bean: class [org.springframework.aop.aspectj.AspectJAroundAdvice]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
AspectJAroundAdvice的属性constructorArgumentValues可以看到有下面三个:这三个实例化需要用无参构造,advice和advisor用有参构造。点进去可以看到除了advice依赖的这三个 其余均有有参构造函数。
这个操作是实例化生成所有advisor对象,包括解析的xml文件的配置以及注解实现的切面方式。
findAdvisorBeans:102, BeanFactoryAdvisorRetrievalHelper (org.springframework.aop.framework.autoproxy)
findCandidateAdvisors:131, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
findCandidateAdvisors:100, AnnotationAwareAspectJAutoProxyCreator (org.springframework.aop.aspectj.annotation)
shouldSkip:110, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
postProcessBeforeInstantiation:262, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsBeforeInstantiation:1396, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
resolveBeforeInstantiation:1365, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)这个方法是用户自定义实现动态代理,这里只生成advisor对象放缓存 不生成代理对象
createBean:618, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:417, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 71399214 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:370, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:414, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:260, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:993, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:1024, AbstractApplicationContext (org.springframework.context.support)
refresh:614, AbstractApplicationContext (org.springframework.context.support)
<init>:150, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:87, ClassPathXmlApplicationContext (org.springframework.context.support)
main:15, TestAop (com.mashibing.aop.xml)
advisor对象在一级缓存中存储。
postProcessBeforeInstantiation:274, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
targetSource这里为空 则不会进入后续创建代理方法。
resolveBeforeInstantiation:1365, AbstractAutowireCapableBeanFactory这里没有生成代理对象,后续方法会继续生成:
resolveBeforeInstantiation已经执行过最上面的部分,shouldskip实例化advisor这里再执行会去取缓存
判断对象是否要被拦截执行生成代理对象,这一步判断切点表达式的匹配