91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

spring-AOP原理與應用

發布時間:2020-06-23 00:23:01 來源:網絡 閱讀:5649 作者:叫我北北 欄目:開發技術
spring-AOP原理與應用

spring-AOP原理與應用


什么是AOP

spring-AOP原理與應用

Spring是解決實際開發中的一些問題:

* AOP解決OOP中遇到的一些問題.OOP的延續和擴展.

AOP作用

    對程序進行增強:不修改源碼的情況下.

    * AOP可以進行權限校驗,日志記錄,性能監控,事務控制.

SpringAOP的由來:

    AOP最早由AOP聯盟的組織提出的,制定了一套規范.SpringAOP思想引入到框架中,必須遵守AOP聯盟的規范.

底層實現:

    代理機制:

    * Spring的AOP的底層用到兩種代理機制:

        * JDK的動態代理 :針對實現了接口的類產生代理.

        * Cglib的動態代理 :針對沒有實現接口的類產生代理. 應用的是底層的字節碼增強的技術 生成當前類的子類對象.

 

動態代理

1 運行時實現指定的接口

想實現某個接口,你需要寫一個類,然后在類名字的后面給出“implementsXXX接口。這才是實現某個接口:

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數組中指定的接口。沒錯,返回值miMyInterface接口的實現類。你不要問這個類是哪個類,你只需要知道miMyInterface接口的實現類就可以了。你現在也不用去管loaderh這兩個參數是什么東東,你只需要知道,Proxy類的靜態方法newProxyInstance()方法返回的方法是實現了指定接口的實現類對象,甚至你都沒有看見實現類的代碼。

動態代理就是在運行時生成一個類,這個類會實現你指定的一組接口,而這個類沒有.java文件,是在運行時生成的,你也不用去關心它是什么類型的,你只需要知道它實現了哪些接口即可。

2 newProxyInstance()方法的參數

Proxy類的newInstance()方法有三個參數:

ClassLoader loader:它是類加載器類型,你不用去理睬它,你只需要知道怎么可以獲得它就可以了:MyInterface.class.getClassLoader()就可以獲取到ClassLoader對象,沒錯,只要你有一個Class對象就可以獲取到ClassLoader對象;

Class[] interfaces:指定newProxyInstance()方法返回的對象要實現哪些接口,沒錯,可以指定多個接口,例如上面例子只我們只指定了一個接口:Class[] cs = {MyInterface.class};

InvocationHandler h:它是最重要的一個參數!它是一個接口!它的名字叫調用處理器!你想一想,上面例子中mi對象是MyInterface接口的實現類對象,那么它一定是可以調用fun1()fun2()方法了,難道你不想調用一下fun1()fun2()方法么,它會執行些什么東東呢?其實無論你調用代理對象的什么方法,它都是在調用InvocationHandlerinvoke()方法!

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()方法!它是對代理對象所有方法的唯一實現。也就是說,無論你調用代理對象上的哪個方法,其實都是在調用InvocationHandlerinvoke()方法。

想象中的類:

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()方法。

3 InvocationHandlerinvoke()方法

spring-AOP原理與應用


InvocationHandler的invoke()方法的參數有三個:

Object proxy:代理對象,也就是Proxy.newProxyInstance()方法返回的對象,通常我們用不上它;

Method method:表示當前被調用方法的反射對象,例如mi.fun1(),那么method就是fun1()方法的反射對象;

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();
}

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

spring-AOP原理與應用


引入Spring的配置文件

引入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..*.*(..)

案例

spring-AOP原理與應用


其他的增強的配置:
<!-- 配置切面類 -->
<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>


Spring使用AspectJ進行AOP的開發:注解的方式

引入相關的jar:
引入Spring的配置文件

引入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注解的自動代理:
<aop:aspectj-autoproxy/>
AspectJAOP的注解:

@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-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;

}




向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

缙云县| 沙湾县| 喜德县| 阳西县| 洛川县| 浦东新区| 江西省| 昌宁县| 普兰县| 祥云县| 洛川县| 新安县| 浦东新区| 商都县| 乌兰察布市| 柏乡县| 仙桃市| 长治县| 儋州市| 治多县| 马鞍山市| 临沧市| 太湖县| 安陆市| 哈巴河县| 湖南省| 宜良县| 理塘县| 尼玛县| 仁布县| 淮滨县| 巧家县| 上蔡县| 龙南县| 宜春市| 济阳县| 襄垣县| 东源县| 沂源县| 喀喇| 腾冲县|