spring-AOP原理与应用
Spring是解决实际开发中的一些问题:
* AOP解决OOP中遇到的一些问题.是OOP的延续和扩展.
AOP作用对程序进行增强:不修改源码的情况下.
* AOP可以进行权限校验,日志记录,性能监控,事务控制.
Spring的AOP的由来:AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范.
底层实现:代理机制:
* Spring的AOP的底层用到两种代理机制:
* JDK的动态代理 :针对实现了接口的类产生代理.
* Cglib的动态代理:针对没有实现接口的类产生代理. 应用的是底层的字节码增强的技术 生成当前类的子类对象.
动态代理1 运行时实现指定的接口想实现某个接口,你需要写一个类,然后在类名字的后面给出“implements”XXX接口。这才是实现某个接口:
publicinterfaceMyInterface{voidfun1();voidfun2();}publicclassMyInterfaceImplimplementsMyInterface{publicvoidfun1(){System.out.println("fun1()");}publicvoidfun2(){System.out.println("fun2()");}}
上面的代码对我们来说没有什么新鲜感,我们要说的是动态代理技术可以通过一个方法调用就可以生成一个对指定接口的实现类对象。
Class[] cs = {MyInterface.class};
MyInterface mi = (MyInterface)Proxy.newProxyInstance(loader, cs, h);
上面代码中,Proxy类的静态方法newProxyInstance()方法生成了一个对象,这个对象实现了cs数组中指定的接口。没错,返回值mi是MyInterface接口的实现类。你不要问这个类是哪个类,你只需要知道mi是MyInterface接口的实现类就可以了。你现在也不用去管loader和h这两个参数是什么东东,你只需要知道,Proxy类的静态方法newProxyInstance()方法返回的方法是实现了指定接口的实现类对象,甚至你都没有看见实现类的代码。
动态代理就是在运行时生成一个类,这个类会实现你指定的一组接口,而这个类没有.java文件,是在运行时生成的,你也不用去关心它是什么类型的,你只需要知道它实现了哪些接口即可。
2 newProxyInstance()方法的参数Proxy类的newInstance()方法有三个参数:
lClassLoader loader:它是类加载器类型,你不用去理睬它,你只需要知道怎么可以获得它就可以了:MyInterface.class.getClassLoader()就可以获取到ClassLoader对象,没错,只要你有一个Class对象就可以获取到ClassLoader对象;
lClass[] interfaces:指定newProxyInstance()方法返回的对象要实现哪些接口,没错,可以指定多个接口,例如上面例子只我们只指定了一个接口:Class[] cs = {MyInterface.class};
lInvocationHandler h:它是最重要的一个参数!它是一个接口!它的名字叫调用处理器!你想一想,上面例子中mi对象是MyInterface接口的实现类对象,那么它一定是可以调用fun1()和fun2()方法了,难道你不想调用一下fun1()和fun2()方法么,它会执行些什么东东呢?其实无论你调用代理对象的什么方法,它都是在调用InvocationHandler的invoke()方法!
publicstaticvoidmain(String[]args){Class[]cs={MyInterface.class};ClassLoaderloader=MyInterface.class.getClassLoader();InvocationHandlerh=newInvocationHandler(){publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println("无论你调用代理对象的什么方法,其实都是在调用invoke()...");returnnull;}};MyInterfacemi=(MyInterface)Proxy.newProxyInstance(loader,cs,h);mi.fun1();mi.fun2();}
InvocationHandler接口只有一个方法,即invoke()方法!它是对代理对象所有方法的唯一实现。也就是说,无论你调用代理对象上的哪个方法,其实都是在调用InvocationHandler的invoke()方法。
想象中的类:
classXimplementsMyInterface{privateInvocationHandlerh;publicX(InvocationHandlerh){this.h=h;}publicvoidfun1(){h.invoke();}publicvoidfun2(){h.invoke();}}
注意,X类是我们用来理解代理对象与InvocationHandler之间的关系的,但它是不存在的类。是我们想象出来的!也就是说,它是用来说明,无论你调用代理对象的哪个方法,最终调用的都是调用处理器的invoke()方法。
3 InvocationHandler的invoke()方法InvocationHandler的invoke()方法的参数有三个:
lObject proxy:代理对象,也就是Proxy.newProxyInstance()方法返回的对象,通常我们用不上它;
lMethod method:表示当前被调用方法的反射对象,例如mi.fun1(),那么method就是fun1()方法的反射对象;
lObject[] args:表示当前被调用方法的参数,当然mi.fun1()这个调用是没有参数的,所以args是一个零长数组。
最后要说的是invoke()方法的返回值为Object类型,它表示当前被调用的方法的返回值,当然mi.fun1()方法是没有返回值的,所以invoke()返回的就必须是null了。
publicstaticvoidmain(String[]args){Class[]cs={MyInterface.class};ClassLoaderloader=MyInterface.class.getClassLoader();InvocationHandlerh=newInvocationHandler(){publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println("当前调用的方法是:"+method.getName());returnnull;}};MyInterfacemi=(MyInterface)Proxy.newProxyInstance(loader,cs,h);mi.fun1();mi.fun2();}AOP的开发中的相关术语:
Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点.
Pointcut(切入点):所谓切入点是指我们要对哪些Joinpoint进行拦截的定义.
Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.
Target(目标对象):代理的目标对象
Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程.
spring采用动态代理织入,而AspectJ采用编译期织入和类装在期织入
Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类
Aspect(切面): 是切入点和通知(引介)的结合
Spring使用AspectJ进行AOP的开发:XML的方式引入相应的jar包* spring的传统AOP的开发的包
spring-aop-4.2.4.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
* aspectJ的开发包:
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
spring-aspects-4.2.4.RELEASE.jar
引入AOP约束:
<beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"></beans>
前置通知 :在目标方法执行之前执行
后置通知 :在目标方法执行之后执行
环绕通知 :在目标方法执行前和执行后执行
异常抛出通知:在目标方法执行出现 异常的时候执行
最终通知 :无论目标方法是否出现异常最终通知都会执行
切入点表达式execution(表达式)
表达式:
[方法访问修饰符] 方法返回值 包名.类名.方法名(方法的参数)
public * cn.spring.dao.*.*(..)
* cn.spring.dao.*.*(..)
* cn.spring.dao.UserDao+.*(..)
* cn.spring.dao..*.*(..)
案例<!--配置切面类--><beanid="myAspectXml"class="cn.itcast.spring.demo3.MyAspectXml"></bean><!--进行aop的配置--><aop:config><!--配置切入点表达式:哪些类的哪些方法需要进行增强--><aop:pointcutexpression="execution(*cn.spring.demo3.*Dao.save(..))"id="pointcut1"/><aop:pointcutexpression="execution(*cn.spring.demo3.*Dao.delete(..))"id="pointcut2"/><aop:pointcutexpression="execution(*cn.spring.demo3.*Dao.update(..))"id="pointcut3"/><aop:pointcutexpression="execution(*cn.spring.demo3.*Dao.find(..))"id="pointcut4"/><!--配置切面--><aop:aspectref="myAspectXml"><aop:beforemethod="before"pointcut-ref="pointcut1"/><aop:after-returningmethod="afterReturing"pointcut-ref="pointcut2"/><aop:aroundmethod="around"pointcut-ref="pointcut3"/><aop:after-throwingmethod="afterThrowing"pointcut-ref="pointcut4"/><aop:aftermethod="after"pointcut-ref="pointcut4"/></aop:aspect></aop:config>
Spring使用AspectJ进行AOP的开发:注解的方式引入相关的jar包:引入Spring的配置文件
引入AOP约束:
<beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"></beans>编写目标类:
publicclassProductDao{publicvoidsave(){System.out.println("保存商品...");}publicvoidupdate(){System.out.println("修改商品...");}publicvoiddelete(){System.out.println("删除商品...");}publicvoidfind(){System.out.println("查询商品...");}}配置目标类:
<!--目标类============--><beanid="productDao"class="cn.spring.demo4.ProductDao"></bean>
开启aop注解的自动代理:<aop:aspectj-autoproxy/>AspectJ的AOP的注解:
@Aspect:定义切面类的注解
通知类型:
* @Before :前置通知
* @AfterReturing :后置通知
* @Around :环绕通知
* @After :最终通知
* @AfterThrowing :异常抛出通知.
@Pointcut:定义切入点的注解
编写切面类:@AspectpublicclassMyAspectAnno{@Before("MyAspectAnno.pointcut1()")publicvoidbefore(){System.out.println("前置通知===========");}@Pointcut("execution(*cn.spring.demo4.ProductDao.save(..))")privatevoidpointcut1(){}}
<!--配置切面类--><beanid="myAspectAnno"class="cn.spring.demo4.MyAspectAnno"></bean>
其他通知的注解:@AspectpublicclassMyAspectAnno{@Before("MyAspectAnno.pointcut1()")publicvoidbefore(){System.out.println("前置通知===========");}@AfterReturning("MyAspectAnno.pointcut2()")publicvoidafterReturning(){System.out.println("后置通知===========");}@Around("MyAspectAnno.pointcut3()")publicObjectaround(ProceedingJoinPointjoinPoint)throwsThrowable{System.out.println("环绕前通知==========");Objectobj=joinPoint.proceed();System.out.println("环绕后通知==========");returnobj;}@AfterThrowing("MyAspectAnno.pointcut4()")publicvoidafterThrowing(){System.out.println("异常抛出通知========");}@After("MyAspectAnno.pointcut4()")publicvoidafter(){System.out.println("最终通知==========");}@Pointcut("execution(*cn.itcast.spring.demo4.ProductDao.save(..))")privatevoidpointcut1(){}@Pointcut("execution(*cn.itcast.spring.demo4.ProductDao.update(..))")privatevoidpointcut2(){}@Pointcut("execution(*cn.itcast.spring.demo4.ProductDao.delete(..))")privatevoidpointcut3(){}@Pointcut("execution(*cn.itcast.spring.demo4.ProductDao.find(..))")privatevoidpointcut4(){}}
源码解析
对于上面注解方式的aop操作,我觉得有必要了解一下源码实现,但是总感觉能力很经验还不足以读懂源码,这里先开个头,之后觉得时机到了再读:
spring中的自定义注解,如果声明了自定义注解,那么就一定会在程序中的某个地方注册了对于的解析器,所以找见了上图的类所在的位置。
publicclassAopNamespaceHandlerextendsNamespaceHandlerSupport{/***Registerthe{@linkBeanDefinitionParserBeanDefinitionParsers}forthe*'{@codeconfig}','{@codespring-configured}','{@codeaspectj-autoproxy}'*and'{@codescoped-proxy}'tags.*/@Overridepublicvoidinit(){//In2.0XSDaswellasin2.1XSD.registerBeanDefinitionParser("config",newConfigBeanDefinitionParser());//这里对标签aspectj-autoproxy注册,算是源码的入口registerBeanDefinitionParser("aspectj-autoproxy",newAspectJAutoProxyBeanDefinitionParser());registerBeanDefinitionDecorator("scoped-proxy",newScopedProxyBeanDefinitionDecorator());//Onlyin2.0XSD:movedtocontextnamespaceasof2.1registerBeanDefinitionParser("spring-configured",newSpringConfiguredBeanDefinitionParser());}}
一旦遇到注解就会使用解析器AspectJAutoProxyBeanDefinitionParser进行解析,它解析的代码逻辑是:
classAspectJAutoProxyBeanDefinitionParserimplementsBeanDefinitionParser{@Override@NullablepublicBeanDefinitionparse(Elementelement,ParserContextparserContext){AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext,element);extendBeanDefinition(element,parserContext);returnnull;}privatevoidextendBeanDefinition(Elementelement,ParserContextparserContext){BeanDefinitionbeanDef=parserContext.getRegistry().getBeanDefinition(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);if(element.hasChildNodes()){addIncludePatterns(element,parserContext,beanDef);}}privatevoidaddIncludePatterns(Elementelement,ParserContextparserContext,BeanDefinitionbeanDef){ManagedList<TypedStringValue>includePatterns=newManagedList<>();NodeListchildNodes=element.getChildNodes();for(inti=0;i<childNodes.getLength();i++){Nodenode=childNodes.item(i);if(nodeinstanceofElement){ElementincludeElement=(Element)node;TypedStringValuevalueHolder=newTypedStringValue(includeElement.getAttribute("name"));valueHolder.setSource(parserContext.extractSource(includeElement));includePatterns.add(valueHolder);}}if(!includePatterns.isEmpty()){includePatterns.setSource(parserContext.extractSource(element));beanDef.getPropertyValues().add("includePatterns",includePatterns);}}}
AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser,对于BeanDefinitionParser接口的统一实现都是从parse函数开始的。
publicstaticvoidregisterAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContextparserContext,ElementsourceElement){//1.注册或者升级BeanDefinitionBeanDefinitionbeanDefinition=AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext.getRegistry(),parserContext.extractSource(sourceElement));//2.处理proxy-target-class以及expose-proxy属性useClassProxyingIfNecessary(parserContext.getRegistry(),sourceElement);//注册组件并通知监听registerComponentIfNecessary(beanDefinition,parserContext);}
到这就是对自定义注解的处理代码,具体逻辑由于类太多还整理不了。
结合网上看的资料,对于创建aop代码可以分为以下步骤:
1.获取增强器或者获取增强方法
2.根据获取的增强进行代理,(创建代码的方式是通过代理工厂实现的:)
核心类是:
publicabstractclassAbstractAutoProxyCreatorextendsProxyProcessorSupportimplementsSmartInstantiationAwareBeanPostProcessor,BeanFactoryAware{@NullableprotectedstaticfinalObject[]DO_NOT_PROXY=null;protectedstaticfinalObject[]PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS=newObject[0];protectedfinalLoglogger=LogFactory.getLog(getClass());privateAdvisorAdapterRegistryadvisorAdapterRegistry=GlobalAdvisorAdapterRegistry.getInstance();privatebooleanfreezeProxy=false;privateString[]interceptorNames=newString[0];privatebooleanapplyCommonInterceptorsFirst=true;@NullableprivateTargetSourceCreator[]customTargetSourceCreators;@NullableprivateBeanFactorybeanFactory;privatefinalSet<String>targetSourcedBeans=Collections.newSetFromMap(newConcurrentHashMap<>(16));privatefinalSet<Object>earlyProxyReferences=Collections.newSetFromMap(newConcurrentHashMap<>(16));privatefinalMap<Object,Class<?>>proxyTypes=newConcurrentHashMap<>(16);privatefinalMap<Object,Boolean>advisedBeans=newConcurrentHashMap<>(256);@OverridepublicvoidsetFrozen(booleanfrozen){this.freezeProxy=frozen;}@OverridepublicbooleanisFrozen(){returnthis.freezeProxy;}publicvoidsetAdvisorAdapterRegistry(AdvisorAdapterRegistryadvisorAdapterRegistry){this.advisorAdapterRegistry=advisorAdapterRegistry;}publicvoidsetCustomTargetSourceCreators(TargetSourceCreator...targetSourceCreators){this.customTargetSourceCreators=targetSourceCreators;}publicvoidsetInterceptorNames(String...interceptorNames){this.interceptorNames=interceptorNames;}publicvoidsetApplyCommonInterceptorsFirst(booleanapplyCommonInterceptorsFirst){this.applyCommonInterceptorsFirst=applyCommonInterceptorsFirst;}@OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory){this.beanFactory=beanFactory;}@NullableprotectedBeanFactorygetBeanFactory(){returnthis.beanFactory;}@Override@NullablepublicClass<?>predictBeanType(Class<?>beanClass,StringbeanName){if(this.proxyTypes.isEmpty()){returnnull;}ObjectcacheKey=getCacheKey(beanClass,beanName);returnthis.proxyTypes.get(cacheKey);}@Override@NullablepublicConstructor<?>[]determineCandidateConstructors(Class<?>beanClass,StringbeanName)throwsBeansException{returnnull;}@OverridepublicObjectgetEarlyBeanReference(Objectbean,StringbeanName)throwsBeansException{ObjectcacheKey=getCacheKey(bean.getClass(),beanName);if(!this.earlyProxyReferences.contains(cacheKey)){this.earlyProxyReferences.add(cacheKey);}returnwrapIfNecessary(bean,beanName,cacheKey);}@OverridepublicObjectpostProcessBeforeInstantiation(Class<?>beanClass,StringbeanName)throwsBeansException{ObjectcacheKey=getCacheKey(beanClass,beanName);if(!StringUtils.hasLength(beanName)||!this.targetSourcedBeans.contains(beanName)){if(this.advisedBeans.containsKey(cacheKey)){returnnull;}if(isInfrastructureClass(beanClass)||shouldSkip(beanClass,beanName)){this.advisedBeans.put(cacheKey,Boolean.FALSE);returnnull;}}//CreateproxyhereifwehaveacustomTargetSource.//Suppressesunnecessarydefaultinstantiationofthetargetbean://TheTargetSourcewillhandletargetinstancesinacustomfashion.TargetSourcetargetSource=getCustomTargetSource(beanClass,beanName);if(targetSource!=null){if(StringUtils.hasLength(beanName)){this.targetSourcedBeans.add(beanName);}Object[]specificInterceptors=getAdvicesAndAdvisorsForBean(beanClass,beanName,targetSource);Objectproxy=createProxy(beanClass,beanName,specificInterceptors,targetSource);this.proxyTypes.put(cacheKey,proxy.getClass());returnproxy;}returnnull;}@OverridepublicbooleanpostProcessAfterInstantiation(Objectbean,StringbeanName){returntrue;}@OverridepublicPropertyValuespostProcessPropertyValues(PropertyValuespvs,PropertyDescriptor[]pds,Objectbean,StringbeanName){returnpvs;}@OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName){returnbean;}//*********可以从这里看整个类的代码@OverridepublicObjectpostProcessAfterInitialization(@NullableObjectbean,StringbeanName)throwsBeansException{if(bean!=null){ObjectcacheKey=getCacheKey(bean.getClass(),beanName);if(!this.earlyProxyReferences.contains(cacheKey)){//如果适合被代理,则需要封装指定的beanreturnwrapIfNecessary(bean,beanName,cacheKey);}}returnbean;}protectedObjectgetCacheKey(Class<?>beanClass,@NullableStringbeanName){if(StringUtils.hasLength(beanName)){return(FactoryBean.class.isAssignableFrom(beanClass)?BeanFactory.FACTORY_BEAN_PREFIX+beanName:beanName);}else{returnbeanClass;}}protectedObjectwrapIfNecessary(Objectbean,StringbeanName,ObjectcacheKey){if(StringUtils.hasLength(beanName)&&this.targetSourcedBeans.contains(beanName)){returnbean;}if(Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))){returnbean;}if(isInfrastructureClass(bean.getClass())||shouldSkip(bean.getClass(),beanName)){this.advisedBeans.put(cacheKey,Boolean.FALSE);returnbean;}//Createproxyifwehaveadvice.如果存在增强方法则创建增强Object[]specificInterceptors=getAdvicesAndAdvisorsForBean(bean.getClass(),beanName,null);if(specificInterceptors!=DO_NOT_PROXY){this.advisedBeans.put(cacheKey,Boolean.TRUE);//创建代理Objectproxy=createProxy(bean.getClass(),beanName,specificInterceptors,newSingletonTargetSource(bean));this.proxyTypes.put(cacheKey,proxy.getClass());returnproxy;}this.advisedBeans.put(cacheKey,Boolean.FALSE);returnbean;}protectedbooleanisInfrastructureClass(Class<?>beanClass){booleanretVal=Advice.class.isAssignableFrom(beanClass)||Pointcut.class.isAssignableFrom(beanClass)||Advisor.class.isAssignableFrom(beanClass)||AopInfrastructureBean.class.isAssignableFrom(beanClass);if(retVal&&logger.isTraceEnabled()){logger.trace("Didnotattempttoauto-proxyinfrastructureclass["+beanClass.getName()+"]");}returnretVal;}protectedbooleanshouldSkip(Class<?>beanClass,StringbeanName){returnfalse;}@NullableprotectedTargetSourcegetCustomTargetSource(Class<?>beanClass,StringbeanName){//Wecan'tcreatefancytargetsourcesfordirectlyregisteredsingletons.if(this.customTargetSourceCreators!=null&&this.beanFactory!=null&&this.beanFactory.containsBean(beanName)){for(TargetSourceCreatortsc:this.customTargetSourceCreators){TargetSourcets=tsc.getTargetSource(beanClass,beanName);if(ts!=null){//FoundamatchingTargetSource.if(logger.isDebugEnabled()){logger.debug("TargetSourceCreator["+tsc+"foundcustomTargetSourceforbeanwithname'"+beanName+"'");}returnts;}}}//NocustomTargetSourcefound.returnnull;}/*创建代理,spring都委托给proxyfactory去处理,在下面进行了一些初始化操作,主要包括以下内容:1.获取当前类中的属性2.添加代理接口3.封装advisor并加入到ProxyFactory中4.设置需要代理的类5.对ProxyFactory进一步封装6.进行获取代理操作*/protectedObjectcreateProxy(Class<?>beanClass,@NullableStringbeanName,@NullableObject[]specificInterceptors,TargetSourcetargetSource){if(this.beanFactoryinstanceofConfigurableListableBeanFactory){AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory,beanName,beanClass);}ProxyFactoryproxyFactory=newProxyFactory();//获取相关的属性proxyFactory.copyFrom(this);//if(!proxyFactory.isProxyTargetClass()){if(shouldProxyTargetClass(beanClass,beanName)){proxyFactory.setProxyTargetClass(true);}else{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);}returnproxyFactory.getProxy(getProxyClassLoader());}protectedbooleanshouldProxyTargetClass(Class<?>beanClass,@NullableStringbeanName){return(this.beanFactoryinstanceofConfigurableListableBeanFactory&&AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory)this.beanFactory,beanName));}protectedbooleanadvisorsPreFiltered(){returnfalse;}protectedAdvisor[]buildAdvisors(@NullableStringbeanName,@NullableObject[]specificInterceptors){//Handleprototypescorrectly...Advisor[]commonInterceptors=resolveInterceptorNames();List<Object>allInterceptors=newArrayList<>();if(specificInterceptors!=null){allInterceptors.addAll(Arrays.asList(specificInterceptors));if(commonInterceptors.length>0){if(this.applyCommonInterceptorsFirst){allInterceptors.addAll(0,Arrays.asList(commonInterceptors));}else{allInterceptors.addAll(Arrays.asList(commonInterceptors));}}}if(logger.isDebugEnabled()){intnrOfCommonInterceptors=commonInterceptors.length;intnrOfSpecificInterceptors=(specificInterceptors!=null?specificInterceptors.length:0);logger.debug("Creatingimplicitproxyforbean'"+beanName+"'with"+nrOfCommonInterceptors+"commoninterceptorsand"+nrOfSpecificInterceptors+"specificinterceptors");}Advisor[]advisors=newAdvisor[allInterceptors.size()];for(inti=0;i<allInterceptors.size();i++){advisors[i]=this.advisorAdapterRegistry.wrap(allInterceptors.get(i));}returnadvisors;}privateAdvisor[]resolveInterceptorNames(){BeanFactorybf=this.beanFactory;ConfigurableBeanFactorycbf=(bfinstanceofConfigurableBeanFactory?(ConfigurableBeanFactory)bf:null);List<Advisor>advisors=newArrayList<>();for(StringbeanName:this.interceptorNames){if(cbf==null||!cbf.isCurrentlyInCreation(beanName)){Assert.state(bf!=null,"BeanFactoryrequiredforresolvinginterceptornames");Objectnext=bf.getBean(beanName);advisors.add(this.advisorAdapterRegistry.wrap(next));}}returnadvisors.toArray(newAdvisor[advisors.size()]);}protectedvoidcustomizeProxyFactory(ProxyFactoryproxyFactory){}@NullableprotectedabstractObject[]getAdvicesAndAdvisorsForBean(Class<?>beanClass,StringbeanName,@NullableTargetSourcecustomTargetSource)throwsBeansException;}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。