亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

Spring源碼如何實現動態代理

發布時間:2021-03-29 10:51:52 來源:億速云 閱讀:165 作者:小新 欄目:開發技術

小編給大家分享一下Spring源碼如何實現動態代理,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

注:這里不闡述Spring和AOP的一些基本概念和用法,直接進入正題。

流程

??Spring所管理的對象大體會經過確定實例化對象類型、推斷構造方法創建對象(實例化)、設置屬性、初始化等等步驟。在對象初始化階段,Spring為開發者提供了一個BeanPostProcessor接口,它會在對象初始化之前和初始化之后被調用(初始化,不是實例化,對應實例化的是InstantiationAwareBeanPostProcessor接口)。

public interface BeanPostProcessor {
	//初始化之前
	Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
	//初始化之后
	Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

}

??在對象初始化之后會調用postProcessAfterInitialization方法,該方法返回一個Object。如果成功返回了一個對象,那么容器中相應beanName對應的實例就將會是這個對象。

??本文主要分析動態代理,我們著重看AnnotationAwareAspectJAutoProxyCreator。先來看一下它的繼承關系:

Spring源碼如何實現動態代理

??AnnotationAwareAspectJAutoProxyCreator最終實現了BeanPostProcessor接口(也實現了InstantiationAwareBeanPostProcessor接口),可以看到繼承關系比較復雜。當前我們關注的postProcessAfterInitialization方法實現在它的父類AbstractAutoProxyCreator中(只保留了部分代碼):

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (!this.earlyProxyReferences.contains(cacheKey)) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

??這里主要看看wrapIfNecessary方法(只保留了部分代碼):

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		......
		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;
		}
		......
}

??其中核心的是兩個方法調用,分別是getAdvicesAndAdvisorsForBean和createProxy。getAdvicesAndAdvisorsForBean會返回一個對象數組,包含aop相關的一些對象,如果是一個普通的不需要代理的對象會返回一個空Object數組,也就是DO_NOT_PROXY;createProxy方法則是創建代理類。

??先看看getAdvicesAndAdvisorsForBean方法:

protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource customTargetSource) throws BeansException;

??getAdvicesAndAdvisorsForBean方法在當前類(AbstractAutoProxyCreator)中是一個抽象方法,由子類AbstractAdvisorAutoProxyCreator實現:

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
	@Override
	protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}
}

??代碼很清晰,我們進入findEligibleAdvisors方法,看方法名也知道它會完成尋找Advisor的工作:

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		//尋找Advisor
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		//針對指定的bean,過濾可用的Advisor,比如根據注解匹配
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

??首先進入findCandidateAdvisors方法:

protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		List<Advisor> advisors = super.findCandidateAdvisors();
		// Build Advisors for all AspectJ aspects in the bean factory.
		advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		return advisors;
	}

??我們這里主要看看aspectj的邏輯,所以看看aspectJAdvisorsBuilder.buildAspectJAdvisors方法(只保留了主要代碼):

public List<Advisor> buildAspectJAdvisors() {
		List<String> aspectNames = null;
		......
		synchronized (this) {
			aspectNames = this.aspectBeanNames;
			if (aspectNames == null) {
				//獲取所有管理的beanName
				String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
				//遍歷每個beanName
				for (String beanName : beanNames) {
					//從beanFactory獲取Class
					Class<?> beanType = this.beanFactory.getType(beanName);
					//檢查對應的Class是否實現Aspect注解
					if (this.advisorFactory.isAspect(beanType)) {
						//說明這個beanName對應的類是一個切面	
						aspectNames.add(beanName);
						AspectMetadata amd = new AspectMetadata(beanType, beanName);
						if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
							MetadataAwareAspectInstanceFactory factory =
									new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
							//獲取Advisor,主要是解析對象中關于AOP的注解,比如Pointcut
							List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
							if (this.beanFactory.isSingleton(beanName)) {
								//就放入緩存,后面就不用重新解析了
								this.advisorsCache.put(beanName, classAdvisors);
							}
							advisors.addAll(classAdvisors);
						}
					}
				}
				this.aspectBeanNames = aspectNames;
				return advisors;
			}
		}
	......
}

??會從beanFactory中尋找所有管理的beanName,返回一個String數組,然后遍歷數組,從beanFactory中根據beanName獲取對應的Class,然后再看對應的Class是否有Aspect注解,如果有對應的注解,那么就表示這個對象是一個切面。接下來就需要進行解析,生成真正的Advisor對象,最后放入緩存。

??可以看看isAspect方法是如何判斷的:

@Override
	public boolean isAspect(Class<?> clazz) {
		return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
	}
	private boolean hasAspectAnnotation(Class<?> clazz) {
		return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
	}

??邏輯很清晰,主要就是看有沒有Aspect注解。 但是這里要注意,這個buildAspectJAdvisors方法通常不是在這里調用的(”這里“的意思是postProcessAfterInitialization的流程)。回到AnnotationAwareAspectJAutoProxyCreator繼承關系圖中,它也實現了InstantiationAwareBeanPostProcessor接口,同樣在其父類AbstractAutoProxyCreator中實現了postProcessBeforeInstantiation方法,這個方法會在對象實例化(不是初始化)之前調用,在該方法的邏輯里通常會首先觸發buildAspectJAdvisors方法的執行,執行之后會把結果緩存起來。

??好了,再回到findEligibleAdvisors方法,上面代碼已經貼了,這里就不貼了。獲取到Advisor列表之后,要從中找到能用于指定類的Advisor列表,然后返回。接下來就要為指定的對象創建代理對象了,也就是AbstractAutoProxyCreator類的createProxy方法:

	protected Object createProxy(
			Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

		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);
		for (Advisor advisor : advisors) {
			proxyFactory.addAdvisor(advisor);
		}

		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

		return proxyFactory.getProxy(getProxyClassLoader());
	}

??代理對象是由ProxyFactory代理工廠創建的,我們先看看這個工廠是如何創建代理對象的,也就是proxyFactory.getProxy方法:

public Object getProxy(ClassLoader classLoader) {
	return createAopProxy().getProxy(classLoader);
}

??createAopProxy方法會返回一個AopProxy,該方法定義在ProxyFactory的父類ProxyCreatorSupport中:

public class ProxyCreatorSupport extends AdvisedSupport {
	private AopProxyFactory aopProxyFactory;
	public ProxyCreatorSupport() {
		//設置默認的代理工廠DefaultAopProxyFactory
		this.aopProxyFactory = new DefaultAopProxyFactory();
	}
	public AopProxyFactory getAopProxyFactory() {
		//獲取代理工廠,默認就是DefaultAopProxyFactory
		return this.aopProxyFactory;
	}

	protected final synchronized AopProxy createAopProxy() {
		//先獲取代理工廠,然后調用工廠的createAopProxy方法創建AopProxy
		return getAopProxyFactory().createAopProxy(this);
	}
}

??上面貼出了關鍵代碼,getAopProxyFactory默認返回的是一個DefaultAopProxyFactory工廠類,來看看DefaultAopProxyFactory的createAopProxy方法:

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			Class<?> targetClass = config.getTargetClass();
			if (targetClass.isInterface()) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

??代碼中有一些代理配置的判斷,這里不用關心。可以看到它提供了兩個AopProxy,分別是基于JDK的JdkDynamicAopProxy和基于cglib的ObjenesisCglibAopProxy。由于JDK提供的動態代理實現最終生成的代理類默認會繼承Proxy類,實現被代理類實現的接口,因為Java是單繼承,所以只能通過接口實現,也就限制了要使用JDK提供的動態代理,必須要基于接口。而使用cglib基于字節碼的改造則沒有這個限制,所以Spring提供了這兩種方式,根據被代理類的實際情況來選擇。

??關于每個AopProxy是如何創建代理類的,這里就先不跟了~

總結

??總的來說,動態代理是實現AOP的重要手段,Spring提供的動態代理主要依靠其提供的BeanPostProcessor,也稱之為后置處理器。除了BeanPostProcessor之外,還有InstantiationAwareBeanPostProcessor(也繼承了BeanPostProcessor),它們會在bean的生命周期的特定階段被調用,以開放給開發者處理和調整對象的入口或者手段。動態代理依托后置處理器,在后置處理器的邏輯中使用AopProxy創建了被代理對象的代理類,然后代替原有類存入Spring的bean工廠中,之后根據beanName獲取的實例對象就不再是原對象實例,而是代理類。而AopProxy是由AopProxyFactory接口生成,目前該接口只有DefaultAopProxyFactory實現類,其提供了兩種AopProxy,分別基于原生JDK提供的動態代理和cgib,根據實際情況選擇。

Spring源碼如何實現動態代理

看完了這篇文章,相信你對“Spring源碼如何實現動態代理”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

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

AI

大石桥市| 乾安县| 读书| 萨嘎县| 永州市| 乐清市| 安多县| 闵行区| 图片| 江阴市| 新丰县| 汉阴县| 化德县| 樟树市| 雷山县| 永胜县| 阿瓦提县| 博客| 多伦县| 桓仁| 阿克陶县| 石林| 甘孜县| 花垣县| 南昌市| 辽中县| 武安市| 元谋县| 济阳县| 家居| 乐平市| 博乐市| 舞阳县| 镇赉县| 外汇| 夹江县| 寿阳县| 日照市| 乌兰浩特市| 周宁县| 若羌县|