深入解析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
org.springframework.aop.aspectj.annotation.annotationawareaspectjautoproxycreator#findcandidateadvisors
protected list
org.springframework.aop.support.aoputils#findadvisorsthatcanapply
public static list
代理对象的创建
代理对象的创建时机位于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