The IOC provided by Beanfactory is briefly described, and we all know that spring uses the JDK's dynamic proxy to implement AOP, and this is a look at how AOP in spring is going to be.
As mentioned earlier, in the Beanfactory, Getbean will go to Abstractautowirecapablebeanfactory Docreatebean,docreatebean has the following code snippet, Populatebean is mainly XML injection, Initializebean is initialized, and the logic of generating AOP is in Initializebean.
Beanfactory, like its name, only fits the ID, testing AOP here using Classpathxmlapplicationcontext.
Feature |
BeanFactory |
ApplicationContext |
Bean instantiation/wiring |
Yes |
Yes |
Automatic BeanPostProcessor Registration |
No |
Yes |
Automatic BeanFactoryPostProcessor Registration |
No |
Yes |
Convenient MessageSource access (for i18n) |
No |
Yes |
ApplicationEvent Publication
|
No |
Yes |
1 Populatebean (Beanname, MBD, instancewrapper); 2 if NULL ) {3 exposedobject = Initializebean (beanname, Exposedobject, mbd); 4 }
Initializebean will call Applybeanpostprocessorsafterinitialization
1 PublicObject Applybeanpostprocessorsafterinitialization (Object Existingbean, String beanname)2 throwsbeansexception {3 4Object result =Existingbean;5 for(Beanpostprocessor beanprocessor:getbeanpostprocessors ()) {6result =beanprocessor.postprocessafterinitialization (result, beanname);7 if(Result = =NULL) {8 returnresult;9 }Ten } One returnresult; A}
We're only concerned with AOP-related beanpostprocessor, That's org.springframework.aop.framework.autoproxy.infrastructureadvisorautoproxycreator,infrastructureadvisorautoproxycreator. Postprocessafterinitialization calls the postprocessafterinitialization of Abstractautoproxycreator, Postprocessafterinitialization will call Wrapifnecessary again .
1 //there are limitations .2 protectedObject Wrapifnecessary (Object bean, String beanname, Object CacheKey) {3 //Create Proxy If we have advice.4 //get all the candidate advisors, match the advisors and Bean method double traversal, and finally get a list<advisor> that is specificinterceptors5object[] specificinterceptors = Getadvicesandadvisorsforbean (Bean.getclass (), Beanname,NULL);6 if(Specificinterceptors! =do_not_proxy) {7 This. Advisedbeans.put (CacheKey, boolean.true);8 //Key Methods9Object proxy =Createproxy (TenBean.getclass (), Beanname, Specificinterceptors,NewSingletontargetsource (Bean)); One This. Proxytypes.put (CacheKey, Proxy.getclass ()); A returnproxy; - } -}
1 //Abstractautoproxycreator's createproxy, there are limitations.2 protectedObject Createproxy (3Class<?>Beanclass, String beanname, object[] specificinterceptors, Targetsource targetsource) {4 5Proxyfactory proxyfactory =Newproxyfactory ();6 //Copy configuration from the other config object.7Proxyfactory.copyfrom ( This);8 9Advisor[] Advisors =buildadvisors (Beanname, specificinterceptors);Ten for(Advisor advisor:advisors) { One Proxyfactory.addadvisor (advisor); A } - //the target of dynamic proxy can be obtained by Targetsource - Proxyfactory.settargetsource (targetsource); the //GetProxy called Createaopproxy (). GetProxy (ClassLoader), Proxyfactory.createaopproxy () was created by Jdkdynamicaopproxy - returnProxyfactory.getproxy (Getproxyclassloader ()); -}
1 PublicObject getproxy (ClassLoader ClassLoader) {2class<?>[] Proxiedinterfaces = aopproxyutils.completeproxiedinterfaces ( This. Advised,true);3 finddefinedequalsandhashcodemethods (proxiedinterfaces);4 //The dynamic agent of the JDK, because the caller of the GetProxy is Jdkdynamicaopproxy, so here the Invocationhandler is Jdkdynamicaopproxy, the final registration is also agent Bean, Target is hidden from the snow.5 returnProxy.newproxyinstance (ClassLoader, Proxiedinterfaces, This);6}
1 //Jdkdynamicaopproxy's Invoke method, with limitations2 PublicObject Invoke (Object proxy, Method method, object[] args)throwsThrowable {3 methodinvocation invocation;4Object Oldproxy =NULL;5 BooleanSetproxycontext =false;6 7Targetsource Targetsource = This. Advised.targetsource;8Class<?> Targetclass =NULL;9Object target =NULL;Ten One Object RetVal; A - //May is null. Get as late as possible to minimize the time we "own" the target, - //In case it comes from a pool. thetarget =targetsource.gettarget (); - if(Target! =NULL) { -Targetclass =Target.getclass (); - } + - //Get The interception chain for this method. + //assemble the Intercept chain AList<object>chain= This. Advised.getinterceptorsanddynamicinterceptionadvice (method, Targetclass); at - //Check Whether we have any advice. If we don ' t, we can fallback on direct - //reflective invocation of the target, and avoid creating a methodinvocation. - if(Chain.isempty ()) { - //We can skip creating a methodinvocation:just invoke the target directly - //Note that the final invoker must is an invokerinterceptor so we know it does in //Nothing but a reflective operation on the target, and no hot swapping or fancy proxying. -object[] Argstouse =Aopproxyutils.adaptargumentsifnecessary (method, args); to //method of calling target directly by reflection +RetVal =aoputils. invokejoinpointusingreflection (Target, method, Argstouse); - } the Else { * //We need to create a method invocation ... $invocation =Newreflectivemethodinvocation (proxy, Target, method, args, Targetclass, chain);Panax Notoginseng //Proceed to the Joinpoint through the interceptor chain. - //take the Intercept chain. theRetVal =invocation. Proceed (); + } A //return this, the proxy is returned instead of the target the //Massage return value if necessary. +class<?> ReturnType =Method.getreturntype (); - if(RetVal! =NULL&& RetVal = = Target && $ReturnType! = Object.class&& returntype.isinstance (proxy) && $! Rawtargetaccess.class. IsAssignableFrom (Method.getdeclaringclass ())) { - //Special Case:it returned "This" and the return type of the method - //Is type-compatible. Note that we can ' t help if the target sets the //a reference to itself in another returned object. -RetVal =proxy;Wuyi } the - return retVal; Wu -}
Spring-beanfactory Four