您好,登錄后才能下訂單哦!
Spring是解決實際開發中的一些問題:
* AOP解決OOP中遇到的一些問題.是OOP的延續和擴展.
對程序進行增強:不修改源碼的情況下.
* AOP可以進行權限校驗,日志記錄,性能監控,事務控制.
AOP最早由AOP聯盟的組織提出的,制定了一套規范.Spring將AOP思想引入到框架中,必須遵守AOP聯盟的規范.
代理機制:
* Spring的AOP的底層用到兩種代理機制:
* JDK的動態代理 :針對實現了接口的類產生代理.
* Cglib的動態代理 :針對沒有實現接口的類產生代理. 應用的是底層的字節碼增強的技術 生成當前類的子類對象.
想實現某個接口,你需要寫一個類,然后在類名字的后面給出“implements”XXX接口。這才是實現某個接口:
public interface MyInterface { void fun1(); void fun2(); } public class MyInterfaceImpl implements MyInterface { public void fun1() { System.out.println("fun1()"); } public void fun2() { 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文件,是在運行時生成的,你也不用去關心它是什么類型的,你只需要知道它實現了哪些接口即可。
Proxy類的newInstance()方法有三個參數:
l ClassLoader loader:它是類加載器類型,你不用去理睬它,你只需要知道怎么可以獲得它就可以了:MyInterface.class.getClassLoader()就可以獲取到ClassLoader對象,沒錯,只要你有一個Class對象就可以獲取到ClassLoader對象;
l Class[] interfaces:指定newProxyInstance()方法返回的對象要實現哪些接口,沒錯,可以指定多個接口,例如上面例子只我們只指定了一個接口:Class[] cs = {MyInterface.class};
l InvocationHandler h:它是最重要的一個參數!它是一個接口!它的名字叫調用處理器!你想一想,上面例子中mi對象是MyInterface接口的實現類對象,那么它一定是可以調用fun1()和fun2()方法了,難道你不想調用一下fun1()和fun2()方法么,它會執行些什么東東呢?其實無論你調用代理對象的什么方法,它都是在調用InvocationHandler的invoke()方法!
public static void main(String[] args) { Class[] cs = {MyInterface.class}; ClassLoader loader = MyInterface.class.getClassLoader(); InvocationHandler h = new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("無論你調用代理對象的什么方法,其實都是在調用invoke()..."); return null; } }; MyInterface mi = (MyInterface)Proxy.newProxyInstance(loader, cs, h); mi.fun1(); mi.fun2(); }
InvocationHandler接口只有一個方法,即invoke()方法!它是對代理對象所有方法的唯一實現。也就是說,無論你調用代理對象上的哪個方法,其實都是在調用InvocationHandler的invoke()方法。
想象中的類:
class X implements MyInterface { private InvocationHandler h; public X(InvocationHandler h) { this.h = h; } public void fun1() { h.invoke(); } public void fun2() { h.invoke(); } }
注意,X類是我們用來理解代理對象與InvocationHandler之間的關系的,但它是不存在的類。是我們想象出來的!也就是說,它是用來說明,無論你調用代理對象的哪個方法,最終調用的都是調用處理器的invoke()方法。
InvocationHandler的invoke()方法的參數有三個:
l Object proxy:代理對象,也就是Proxy.newProxyInstance()方法返回的對象,通常我們用不上它;
l Method method:表示當前被調用方法的反射對象,例如mi.fun1(),那么method就是fun1()方法的反射對象;
l Object[] args:表示當前被調用方法的參數,當然mi.fun1()這個調用是沒有參數的,所以args是一個零長數組。
最后要說的是invoke()方法的返回值為Object類型,它表示當前被調用的方法的返回值,當然mi.fun1()方法是沒有返回值的,所以invoke()返回的就必須是null了。
public static void main(String[] args) { Class[] cs = {MyInterface.class}; ClassLoader loader = MyInterface.class.getClassLoader(); InvocationHandler h = new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("當前調用的方法是:" + method.getName()); return null; } }; MyInterface mi = (MyInterface)Proxy.newProxyInstance(loader, cs, h); mi.fun1(); mi.fun2(); }
Joinpoint(連接點):所謂連接點是指那些被攔截到的點。在spring中,這些點指的是方法,因為spring只支持方法類型的連接點.
Pointcut(切入點):所謂切入點是指我們要對哪些Joinpoint進行攔截的定義.
Advice(通知/增強):所謂通知是指攔截到Joinpoint之后所要做的事情就是通知.通知分為前置通知,后置通知,異常通知,最終通知,環繞通知(切面要完成的功能)
Introduction(引介):引介是一種特殊的通知在不修改類代碼的前提下, Introduction可以在運行期為類動態地添加一些方法或Field.
Target(目標對象):代理的目標對象
Weaving(織入):是指把增強應用到目標對象來創建新的代理對象的過程.
spring采用動態代理織入,而AspectJ采用編譯期織入和類裝在期織入
Proxy(代理):一個類被AOP織入增強后,就產生一個結果代理類
Aspect(切面): 是切入點和通知(引介)的結合
* 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約束:
<beans xmlns="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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> </beans>
前置通知 :在目標方法執行之前執行
后置通知 :在目標方法執行之后執行
環繞通知 :在目標方法執行前和執行后執行
異常拋出通知:在目標方法執行出現 異常的時候執行
最終通知 :無論目標方法是否出現異常最終通知都會執行
execution(表達式)
表達式:
[方法訪問修飾符] 方法返回值 包名.類名.方法名(方法的參數)
public * cn.spring.dao.*.*(..)
* cn.spring.dao.*.*(..)
* cn.spring.dao.UserDao+.*(..)
* cn.spring.dao..*.*(..)
<!-- 配置切面類 --> <bean id="myAspectXml" class="cn.itcast.spring.demo3.MyAspectXml"></bean> <!-- 進行aop的配置 --> <aop:config> <!-- 配置切入點表達式:哪些類的哪些方法需要進行增強 --> <aop:pointcut expression="execution(* cn.spring.demo3.*Dao.save(..))" id="pointcut1"/> <aop:pointcut expression="execution(* cn.spring.demo3.*Dao.delete(..))" id="pointcut2"/> <aop:pointcut expression="execution(* cn.spring.demo3.*Dao.update(..))" id="pointcut3"/> <aop:pointcut expression="execution(* cn.spring.demo3.*Dao.find(..))" id="pointcut4"/> <!-- 配置切面 --> <aop:aspect ref="myAspectXml"> <aop:before method="before" pointcut-ref="pointcut1"/> <aop:after-returning method="afterReturing" pointcut-ref="pointcut2"/> <aop:around method="around" pointcut-ref="pointcut3"/> <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4"/> <aop:after method="after" pointcut-ref="pointcut4"/> </aop:aspect> </aop:config>
引入AOP約束:
<beans xmlns="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/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> </beans>
public class ProductDao { public void save(){ System.out.println("保存商品..."); } public void update(){ System.out.println("修改商品..."); } public void delete(){ System.out.println("刪除商品..."); } public void find(){ System.out.println("查詢商品..."); } }
<!-- 目標類============ --> <bean id="productDao" class="cn.spring.demo4.ProductDao"></bean>
<aop:aspectj-autoproxy/>
@Aspect:定義切面類的注解
通知類型:
* @Before :前置通知
* @AfterReturing :后置通知
* @Around :環繞通知
* @After :最終通知
* @AfterThrowing :異常拋出通知.
@Pointcut:定義切入點的注解
@Aspect public class MyAspectAnno { @Before("MyAspectAnno.pointcut1()") public void before(){ System.out.println("前置通知==========="); } @Pointcut("execution(* cn.spring.demo4.ProductDao.save(..))") private void pointcut1(){} }
<!-- 配置切面類 --> <bean id="myAspectAnno" class="cn.spring.demo4.MyAspectAnno"></bean>
@Aspect public class MyAspectAnno { @Before("MyAspectAnno.pointcut1()") public void before(){ System.out.println("前置通知==========="); } @AfterReturning("MyAspectAnno.pointcut2()") public void afterReturning(){ System.out.println("后置通知==========="); } @Around("MyAspectAnno.pointcut3()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("環繞前通知=========="); Object obj = joinPoint.proceed(); System.out.println("環繞后通知=========="); return obj; } @AfterThrowing("MyAspectAnno.pointcut4()") public void afterThrowing(){ System.out.println("異常拋出通知========"); } @After("MyAspectAnno.pointcut4()") public void after(){ System.out.println("最終通知=========="); } @Pointcut("execution(* cn.itcast.spring.demo4.ProductDao.save(..))") private void pointcut1(){} @Pointcut("execution(* cn.itcast.spring.demo4.ProductDao.update(..))") private void pointcut2(){} @Pointcut("execution(* cn.itcast.spring.demo4.ProductDao.delete(..))") private void pointcut3(){} @Pointcut("execution(* cn.itcast.spring.demo4.ProductDao.find(..))") private void pointcut4(){} }
源碼解析
對于上面注解方式的aop操作,我覺得有必要了解一下源碼實現,但是總感覺能力很經驗還不足以讀懂源碼,這里先開個頭,之后覺得時機到了再讀:
spring中的自定義注解,如果聲明了自定義注解,那么就一定會在程序中的某個地方注冊了對于的解析器,所以找見了上圖的類所在的位置。
public class AopNamespaceHandler extends NamespaceHandlerSupport { /** * Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the * '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}' * and '{@code scoped-proxy}' tags. */ @Override public void init() { // In 2.0 XSD as well as in 2.1 XSD. registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser()); //這里對標簽aspectj-autoproxy注冊,算是源碼的入口 registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser()); registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator()); // Only in 2.0 XSD: moved to context namespace as of 2.1 registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); } }
一旦遇到注解就會使用解析器AspectJAutoProxyBeanDefinitionParser進行解析,它解析的代碼邏輯是:
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser { @Override @Nullable public BeanDefinition parse(Element element, ParserContext parserContext) { AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element); extendBeanDefinition(element, parserContext); return null; } private void extendBeanDefinition(Element element, ParserContext parserContext) { BeanDefinition beanDef = parserContext.getRegistry().getBeanDefinition(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME); if (element.hasChildNodes()) { addIncludePatterns(element, parserContext, beanDef); } } private void addIncludePatterns(Element element, ParserContext parserContext, BeanDefinition beanDef) { ManagedList<TypedStringValue> includePatterns = new ManagedList<>(); NodeList childNodes = element.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if (node instanceof Element) { Element includeElement = (Element) node; TypedStringValue valueHolder = new TypedStringValue(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函數開始的。
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) { //1.注冊或者升級BeanDefinition BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); //2.處理proxy-target-class以及expose-proxy屬性 useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); //注冊組件并通知監聽 registerComponentIfNecessary(beanDefinition, parserContext); }
到這就是對自定義注解的處理代碼,具體邏輯由于類太多還整理不了。
結合網上看的資料,對于創建aop代碼可以分為以下步驟:
1.獲取增強器或者獲取增強方法
2.根據獲取的增強進行代理,(創建代碼的方式是通過代理工廠實現的:)
核心類是:
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { @Nullable protected static final Object[] DO_NOT_PROXY = null; protected static final Object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS = new Object[0]; protected final Log logger = LogFactory.getLog(getClass()); private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance(); private boolean freezeProxy = false; private String[] interceptorNames = new String[0]; private boolean applyCommonInterceptorsFirst = true; @Nullable private TargetSourceCreator[] customTargetSourceCreators; @Nullable private BeanFactory beanFactory; private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); private final Set<Object> earlyProxyReferences = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16); private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256); @Override public void setFrozen(boolean frozen) { this.freezeProxy = frozen; } @Override public boolean isFrozen() { return this.freezeProxy; } public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) { this.advisorAdapterRegistry = advisorAdapterRegistry; } public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators) { this.customTargetSourceCreators = targetSourceCreators; } public void setInterceptorNames(String... interceptorNames) { this.interceptorNames = interceptorNames; } public void setApplyCommonInterceptorsFirst(boolean applyCommonInterceptorsFirst) { this.applyCommonInterceptorsFirst = applyCommonInterceptorsFirst; } @Override public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; } @Nullable protected BeanFactory getBeanFactory() { return this.beanFactory; } @Override @Nullable public Class<?> predictBeanType(Class<?> beanClass, String beanName) { if (this.proxyTypes.isEmpty()) { return null; } Object cacheKey = getCacheKey(beanClass, beanName); return this.proxyTypes.get(cacheKey); } @Override @Nullable public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException { return null; } @Override public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { this.earlyProxyReferences.add(cacheKey); } return wrapIfNecessary(bean, beanName, cacheKey); } @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { return null; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } // Create proxy here if we have a custom TargetSource. // Suppresses unnecessary default instantiation of the target bean: // The TargetSource will handle target instances in a custom fashion. TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) { return true; } @Override public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) { return pvs; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } //*********可以從這里看整個類的代碼 @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { //如果適合被代理,則需要封裝指定的bean return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } protected Object getCacheKey(Class<?> beanClass, @Nullable String beanName) { if (StringUtils.hasLength(beanName)) { return (FactoryBean.class.isAssignableFrom(beanClass) ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName); } else { return beanClass; } } 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 proxy if we have advice.如果存在增強方法則創建增強 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; } protected boolean isInfrastructureClass(Class<?> beanClass) { boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass); if (retVal && logger.isTraceEnabled()) { logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]"); } return retVal; } protected boolean shouldSkip(Class<?> beanClass, String beanName) { return false; } @Nullable protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) { // We can't create fancy target sources for directly registered singletons. if (this.customTargetSourceCreators != null && this.beanFactory != null && this.beanFactory.containsBean(beanName)) { for (TargetSourceCreator tsc : this.customTargetSourceCreators) { TargetSource ts = tsc.getTargetSource(beanClass, beanName); if (ts != null) { // Found a matching TargetSource. if (logger.isDebugEnabled()) { logger.debug("TargetSourceCreator [" + tsc + " found custom TargetSource for bean with name '" + beanName + "'"); } return ts; } } } // No custom TargetSource found. return null; } /*創建代理,spring都委托給proxyfactory去處理,在下面進行了一些初始化操作,主要包括以下內容: 1.獲取當前類中的屬性 2.添加代理接口 3.封裝advisor并加入到ProxyFactory中 4.設置需要代理的類 5.對ProxyFactory進一步封裝 6.進行獲取代理操作*/ 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()) { 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); } return proxyFactory.getProxy(getProxyClassLoader()); } protected boolean shouldProxyTargetClass(Class<?> beanClass, @Nullable String beanName) { return (this.beanFactory instanceof ConfigurableListableBeanFactory && AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName)); } protected boolean advisorsPreFiltered() { return false; } protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) { // Handle prototypes correctly... Advisor[] commonInterceptors = resolveInterceptorNames(); List<Object> allInterceptors = new ArrayList<>(); 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()) { int nrOfCommonInterceptors = commonInterceptors.length; int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0); logger.debug("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors + " common interceptors and " + nrOfSpecificInterceptors + " specific interceptors"); } Advisor[] advisors = new Advisor[allInterceptors.size()]; for (int i = 0; i < allInterceptors.size(); i++) { advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i)); } return advisors; } private Advisor[] resolveInterceptorNames() { BeanFactory bf = this.beanFactory; ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null); List<Advisor> advisors = new ArrayList<>(); for (String beanName : this.interceptorNames) { if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) { Assert.state(bf != null, "BeanFactory required for resolving interceptor names"); Object next = bf.getBean(beanName); advisors.add(this.advisorAdapterRegistry.wrap(next)); } } return advisors.toArray(new Advisor[advisors.size()]); } protected void customizeProxyFactory(ProxyFactory proxyFactory) { } @Nullable protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource customTargetSource) throws BeansException; }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。