Overview
This chapter analyzes the enhanced acquisition of AOP from the following aspects:
1. Continuing relationship
2. Enhanced Access
As explained in the previous Entry section, the core of AOP is Annotationawareaspectautoproxycreator, and the next step is to analyze this class, first looking at the inheritance relationship:
Then look at the hierarchical relationships of classes, inheriting classes Abstractautoproxycreator, and Abstractautoproxycreator implements the Beanpostprocessor interface:
What does the Beanpostprocessor interface do?
If we want to add some of our own processing before or after the bean instantiation or other configuration initialization, define an implementation class that implements the Beanpostprocessor interface, and then register it in the IOC container:
Look at the interface of the Beanpostprocessor:
Public Interface beanpostprocessor { throws beansexception; throws beansexception;}
In AOP, Abstractautoproxycreator implements the interface and implements the methods in the interface:
PublicObject Postprocessafterinitialization (Object bean, String beanname)throwsbeansexception {if(Bean! =NULL) {Object CacheKey=Getcachekey (Bean.getclass (), beanname); //Build CacheKey based on a given bean and classname in the form of Beanclassname_beanname if(! This. Earlyproxyreferences.contains (CacheKey)) { return wrapifnecessary(Bean, beanname, cacheKey);//Determine if a proxy is required }} returnBean; } /*** Build A cache key for the given Bean class and bean name. * @paramBeanclass The Bean class *@parambeanname The bean name *@returnThe cache key for the given class and name*/ protectedObject Getcachekey (class<?>Beanclass, String beanname) { return beanclass.getname () + "_" + Beanname; } /*** Wrap The given bean if necessary, i.e. if it is eligible for being proxied. * @paramBean The Raw bean instance *@paramBeanname The name of the bean *@paramCacheKey the cache key for metadata access *@returna proxy wrapping the bean, or the raw bean instance As-is*/ protectedObject Wrapifnecessary (Object bean, String beanname, Object CacheKey) {if(Beanname! =NULL&& This. Targetsourcedbeans.contains (Beanname)) {//Whether it has been processedreturnBean; } if(Boolean.FALSE.equals ( This. Advisedbeans.get (CacheKey))) {//No enhancements requiredreturnBean; } if(Isinfrastructureclass (Bean.getclass ()) | |Shouldskip (Bean.getclass (), beanname)) {//is the infrastructure class, does it specify that no proxy is required? This. Advisedbeans.put (CacheKey, Boolean.false); returnBean; } //Create Proxy If we have advice.object[] specificinterceptors = Getadvicesandadvisorsforbean (Bean.getclass (), beanname, null);// Get Enhanced if(Specificinterceptors! =do_not_proxy) {//If enhancements are obtained, you need to create an agent This. Advisedbeans.put (CacheKey, boolean.true); Object proxy = Createproxy (Bean.getclass (), Beanname, Specificinterceptors, new Singletontargetsource (Bean)); This. Proxytypes.put (CacheKey, Proxy.getclass ()); returnproxy; } This. Advisedbeans.put (CacheKey, Boolean.false); returnBean; }
From the above code, the enhanced acquisition starts with the Getadvicesandadvisorsforbean method, and the method in Abstractautoproxycreator is the abstract class, we see the concrete implementation Abstractadvisorautoproxycreator class :
protectedObject[] Getadvicesandadvisorsforbean (class<?>Beanclass, String beanname, Targetsource targetsource) { List <Advisor> advisors = findeligibleadvisors (beanclass, beanname); if(Advisors.isempty ()) {returnDo_not_proxy; } returnAdvisors.toarray (); } /*** Find all eligible Advisors for auto-proxying this class. * @paramBeanclass the Clazz to find advisors for *@paramBeanname The name of the currently proxied Bean *@returnthe empty List, not {@codeNULL}, * If there is no pointcuts or interceptors *@see#findCandidateAdvisors *@see#sortAdvisors *@see#extendAdvisors*/ protectedList<advisor> Findeligibleadvisors (class<?>Beanclass, String beanname) {
Finally, the List of these two methods<Advisor> candidateadvisors = findcandidateadvisors ();//Get all Enhanced List<Advisor> ELIGIBLEADV Isors = findadvisorsthatcanapply (candidateadvisors, Beanclass, beanname);//enhanced for bean enhancement and application extendadvisors (eligibleadvisors); if(!Eligibleadvisors.isempty ()) {eligibleadvisors=sortadvisors (eligibleadvisors); } returneligibleadvisors; }
Findcandidateadvisors (), looking for advisors,
Configuration of AOP
<aop:config proxy-target-Class= "true" > <aop:aspect ref= "Audience" > <aop:pointcut Id= "Performance" expression= "Execution (* com.spring.test.action1.Performer.perform (..))" /> <aop:before pointcut-ref= "Performance" method= "Takeseats"/> <aop:before pointcut-ref= " Performance "method=" Turnoffcellphones "/> <aop:after-returning pointcut-ref=" Performance "method=" Applaud "/> <aop:after-throwing pointcut-ref=" Performance "method=" Demandrefund "/> </aop: Aspect> </aop:config>
PublicList<advisor>Findadvisorbeans () {//determine list of advisor bean names, if not cached already.string[] Advisornames =NULL; synchronized( This) {Advisornames= This. Cachedadvisorbeannames; if(Advisornames = =NULL) { //Do not initialize Factorybeans here:we need to leave all regular beans//Uninitialized to let the Auto-proxy creator apply to them!Advisornames =beanfactoryutils.beannamesfortypeincludingancestors ( //Get all the beans This. Beanfactory, Advisor.class,true,false); This. Cachedadvisorbeannames =Advisornames; } } if(Advisornames.length = = 0) { return NewLinkedlist<advisor>(); } List<Advisor> Advisors =NewLinkedlist<advisor>(); for(String name:advisornames) {if(Iseligiblebean (name)) { //is a valid bean if( This. Beanfactory.iscurrentlyincreation (name)) { if(logger.isdebugenabled ()) {Logger.debug ("Skipping currently created advisor" + name + "'"); } } Else { Try{Advisors.add ( This. Beanfactory.getbean (Name, Advisor.class)); } Catch(Beancreationexception ex) {throwable rootcause=Ex.getmostspecificcause (); if(Rootcauseinstanceofbeancurrentlyincreationexception) {beancreationexception BCE=(beancreationexception) rootcause; if( This. Beanfactory.iscurrentlyincreation (Bce.getbeanname ())) { if(logger.isdebugenabled ()) {Logger.debug ("Skipping advisor" + name + "' with dependency on currently created Bean:" +ex.getmessage ()); } //ignore:indicates A reference back to the bean we ' re trying to advise. //We want to find advisors other than the currently created Bean itself. Continue; } } Throwex; } } } } returnAdvisors; }
Findadvisorsthatcanapply ()
---Enhancement of SPRINGAOP source code