深入解析spring aop原理及源码-mile米乐体育

目录

  • @enableaspectjautoproxy
  • 找切面
  • 代理对象的创建
  • 代理方法的执行
    • exposeinvocationinterceptor#invoke
    • 环绕通知的执行
    • 前置通知的执行
    • 后置通知的执行
    • 返回后通知的执行
    • 异常通知的执行

@enableaspectjautoproxy

@enableaspectjautoproxy注解用于开启aop功能,那么这个注解底层到底做了什么呢?

查看@enableaspectjautoproxy的源码,发现它使用@import注解向spring容器中注入了一个类型为aspectjautoproxyregistrar的bean:

class aspectjautoproxyregistrar implements importbeandefinitionregistrar { @override public void registerbeandefinitions( annotationmetadata importingclassmetadata, beandefinitionregistry registry) { // 注入一个bean名字为org.springframework.aop.config.internalautoproxycreator的aspectjawareadvisorautoproxycreator aopconfigutils.registeraspectjannotationautoproxycreatorifnecessary(registry); annotationattributes enableaspectjautoproxy = annotationconfigutils.attributesfor(importingclassmetadata, enableaspectjautoproxy.class); if (enableaspectjautoproxy != null) { if (enableaspectjautoproxy.getboolean("proxytargetclass")) { // proxytargetclass为true aopconfigutils.forceautoproxycreatortouseclassproxying(registry); } if (enableaspectjautoproxy.getboolean("exposeproxy")) { // exposeproxy为true aopconfigutils.forceautoproxycreatortoexposeproxy(registry); } } } }

aspectjautoproxyregistrar实现了importbeandefinitionregistrar接口,而importbeandefinitionregistrar是spring提供的扩展点之一,主要用来向容器中注入beandefinition,spring会根据beandefinion来生成bean。

那么aspectjautoproxyregistrar到底向容器中注入了什么beandefinion呢?

org.springframework.aop.config.aopconfigutils#registeraspectjannotationautoproxycreatorifnecessary(org.springframework.beans.factory.support.beandefinitionregistry)

@nullable public static beandefinition registeraspectjannotationautoproxycreatorifnecessary(beandefinitionregistry registry) { return registeraspectjannotationautoproxycreatorifnecessary(registry, null); } @nullable public static beandefinition registeraspectjannotationautoproxycreatorifnecessary( beandefinitionregistry registry, @nullable object source) { // annotationawareaspectjautoproxycreator return registerorescalateapcasrequired(annotationawareaspectjautoproxycreator.class, registry, source); } @nullable private static beandefinition registerorescalateapcasrequired( class cls, beandefinitionregistry registry, @nullable 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; } // 注入aspectjawareadvisorautoproxycreator 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; }

从源码可以发现aspectjautoproxyregistrar向容器中注入了一个类型为annotationawareaspectjautoproxycreator的bean。

那么annotationawareaspectjautoproxycreator又是干什么的呢?

annotationawareaspectjautoproxycreator主要实现了三个接口(由父类abstractautoproxycreator实现):

  • 实现了beanfactoryaware,内部持有beanfactory的引用。
  • 实现了smartinstantiationawarebeanpostprocessor(instantiationawarebeanpostprocessor).postprocessbeforeinstantiation,这个方法在bean的实例化(bean创建之前)之前执行。
  • 实现了beanpostprocessor.postprocessbeforeinitialization(),这个方法在bean的初始化之前(bean创建之后,属性被赋值之前)执行,beanpostprocessor.postprocessafterinitialization()在bean的初始化之后执行。

annotationawareaspectjautoproxycreator的继承结构:

找切面

org.springframework.aop.framework.autoproxy.abstractadvisorautoproxycreator#findeligibleadvisors

protected list findeligibleadvisors(class beanclass, string beanname) { /** * @see annotationawareaspectjautoproxycreator#findcandidateadvisors() */ // 获取容器中所有的切面advisor // 这里返回的切面中的方法已经是有序的了,先按注解顺序(around.class, before.class, after.class, afterreturning.class, afterthrowing.class),再按方法名称 list candidateadvisors = findcandidateadvisors(); // 获取所有能够作用于当前bean上的advisor list eligibleadvisors = findadvisorsthatcanapply(candidateadvisors, beanclass, beanname); /** * @see aspectjawareadvisorautoproxycreator#extendadvisors(java.util.list) */ // 往集合第一个位置加入了一个defaultpointcutadvisor extendadvisors(eligibleadvisors); if (!eligibleadvisors.isempty()) { /** * @see aspectjawareadvisorautoproxycreator#sortadvisors(java.util.list) */ // 这里是对切面进行排序,例如有@order注解或者实现了ordered接口 eligibleadvisors = sortadvisors(eligibleadvisors); } return eligibleadvisors; }

org.springframework.aop.aspectj.annotation.annotationawareaspectjautoproxycreator#findcandidateadvisors

protected list findcandidateadvisors() { // add all the spring advisors found according to superclass rules. // 获取容器中所有的切面advisor list advisors = super.findcandidateadvisors(); // build advisors for all aspectj aspects in the bean factory. if (this.aspectjadvisorsbuilder != null) { // 这里还需要解析@aspect注解,生成advisor advisors.addall(this.aspectjadvisorsbuilder.buildaspectjadvisors()); } return advisors; }

org.springframework.aop.support.aoputils#findadvisorsthatcanapply

public static list findadvisorsthatcanapply(list candidateadvisors, class clazz) { if (candidateadvisors.isempty()) { return candidateadvisors; } list eligibleadvisors = new arraylist<>(); // instantiationmodelawarepointcutadvisorimpl for (advisor candidate : candidateadvisors) { if (candidate instanceof introductionadvisor && canapply(candidate, clazz)) { // introductionadvisor类型为引入切面,具体类型为declareparentsadvisor eligibleadvisors.add(candidate); } } boolean hasintroductions = !eligibleadvisors.isempty(); for (advisor candidate : candidateadvisors) { if (candidate instanceof introductionadvisor) { // already processed continue; } // pointcut中的classfilter.match 匹配类 // pointcut中的methodmatcher.match 匹配方法 if (canapply(candidate, clazz, hasintroductions)) { // @aspect,类型为instantiationmodelawarepointcutadvisorimpl eligibleadvisors.add(candidate); } } return eligibleadvisors; }

代理对象的创建

代理对象的创建时机位于bean的初始化之后,因为代理对象内部还是需要去调用目标对象的方法,所以需要让目标对象实例化并完成初始化后才会创建代理对象。

org.springframework.aop.framework.autoproxy.abstractautoproxycreator#postprocessafterinitialization

public object postprocessafterinitialization(@nullable object bean, string beanname) { if (bean != null) { // 先从缓存中获取代理对象 object cachekey = getcachekey(bean.getclass(), beanname); if (this.earlyproxyreferences.remove(cachekey) != bean) { // 按需生成代理对象 return wrapifnecessary(bean, beanname, cachekey); } } return bean; }

org.springframework.aop.framework.autoproxy.abstractautoproxycreator#wrapifnecessary

protected object wrapifnecessary(object bean, string beanname, object cachekey) { if (stringutils.haslength(beanname) && 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 proxyif we have advice. /** * @see abstractadvisorautoproxycreator#getadvicesandadvisorsforbean(java.lang.class, java.lang.string, org.springframework.aop.targetsource) */ // 获取与当前bean匹配的切面 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; }

org.springframework.aop.framework.autoproxy.abstractautoproxycreator#createproxy

protected object createproxy(class beanclass, @nullable string beanname, @nullable 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()) { // 进来说明proxytargetclass=false,指定jdk代理 if (shouldproxytargetclass(beanclass, beanname)) { // 进来这里说明bd中有个属性preservetargetclass=true,可以bd中属性设置的优先级最高 proxyfactory.setproxytargetclass(true); } else { // 这里会判断bean有没有实现接口,没有就只能使用cglib evaluateproxyinterfaces(beanclass, proxyfactory); } } advisor[] advisors = buildadvisors(beanname, specificinterceptors); proxyfactory.addadvisors(advisors); // 切面 proxyfactory.settargetsource(targetsource); // 目标对象 customizeproxyfactory(proxyfactory); proxyfactory.setfrozen(this.freezeproxy); if (advisorsprefiltered()) { proxyfactory.setprefiltered(true); } // 使用jdk或者cglib创建代理对象 return proxyfactory.getproxy(getproxyclassloader()); }

org.springframework.aop.framework.jdkdynamicaopproxy#getproxy(java.lang.classloader)

public object getproxy(@nullable classloader classloader) { if (logger.istraceenabled()) { logger.trace("creating jdk dynamic proxy: " this.advised.gettargetsource()); } class[] proxiedinterfaces = aopproxyutils.completeproxiedinterfaces(this.advised, true); finddefinedequalsandhashcodemethods(proxiedinterfaces); return proxy.newproxyinstance(classloader, proxiedinterfaces, this); }

这里主要看jdk动态代理的实现,proxy.newproxyinstance()的第三个参数为invocationhandler,而这里传的是this,也就是当前的类肯定实现了invocationhandler接口。

代理方法的执行

由于是jdk动态代理,那么代理方法的调用肯定会进入invocationhandler.invoke()方法中,这里的invocationhandler的实现类为org.springframework.aop.framework.jdkdynamicaopproxy。

org.springframework.aop.framework.jdkdynamicaopproxy#invoke

public object invoke(object proxy, method method, object[] args) throws throwable { object oldproxy = null; boolean setproxycontext = false; targetsource targetsource = this.advised.targetsource; object target = null; try { if (!this.equalsdefined && aoputils.isequalsmethod(method)) { // the target does not implement the equals(object) method itself. return equals(args[0]); } else if (!this.hashcodedefined && aoputils.ishashcodemethod(method)) { // the target does not implement the hashcode() method itself. return hashcode(); } else if (method.getdeclaringclass() == decoratingproxy.class) { // there is only getdecoratedclass() declared -> dispatch to proxy config. return aopproxyutils.ultimatetargetclass(this.advised); } else if (!this.advised.opaque && method.getdeclaringclass().isinterface() && method.getdeclaringclass().isassignablefrom(advised.class)) { // service invocations on proxyconfig with the proxy config... return aoputils.invokejoinpointusingreflection(this.advised, method, args); } object retval; if (this.advised.exposeproxy) { // make invocation available if necessary. oldproxy = aopcontext.setcurrentproxy(proxy); setproxycontext = true; } // get as late as possible to minimize the time we "own" the target, // in case it comes from a pool. target = targetsource.gettarget(); // 目标对象 class targetclass = (target != null ? target.getclass() : null); // 目标对象的类型 // get the interception chain for this method. // 这里会对方法进行匹配,因为不是目标对象中的所有方法都需要增强 list

网站地图