成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

Spring源碼學習之動態代理實現流程

瀏覽:2日期:2022-08-15 09:55:11

注:這里不闡述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 {@Overrideprotected 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) {//尋找AdvisorList<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) {//獲取所有管理的beanNameString[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);//遍歷每個beanNamefor (String beanName : beanNames) {//從beanFactory獲取ClassClass<?> 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的注解,比如PointcutList<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方法是如何判斷的:

@Overridepublic 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() {//設置默認的代理工廠DefaultAopProxyFactorythis.aopProxyFactory = new DefaultAopProxyFactory();}public AopProxyFactory getAopProxyFactory() {//獲取代理工廠,默認就是DefaultAopProxyFactoryreturn this.aopProxyFactory;}protected final synchronized AopProxy createAopProxy() {//先獲取代理工廠,然后調用工廠的createAopProxy方法創建AopProxyreturn 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源碼學習之動態代理實現流程的文章就介紹到這了,更多相關Spring動態代理實現內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
正在播放一区二区| 午夜激情一区二区三区| 亚洲精品成a人| 一本一道久久a久久精品| 美女免费视频一区二区| 26uuu另类欧美亚洲曰本| 亚洲九九精品| 国产一级精品在线| 亚洲三级久久久| 欧美中文字幕不卡| 国产综合久久| 国产成人av福利| 亚洲香肠在线观看| 国产婷婷色一区二区三区在线| 亚洲欧美网站| 午夜久久黄色| 精品一区二区免费| 亚洲无人区一区| 国产精品视频一二| 欧美高清视频在线高清观看mv色露露十八 | 久久激情五月婷婷| 国产精品毛片久久久久久| 欧美天堂一区二区三区| 亚洲精品看片| 亚洲天堂久久| 欧美视频网站| 成人app下载| 国内偷窥港台综合视频在线播放| 国产精品视频第一区| 欧美一区二区三区免费在线看| 亚洲精选久久| 黄色亚洲免费| 黄色欧美成人| 91社区在线播放| 国产成人自拍网| 日本va欧美va精品发布| 亚洲乱码国产乱码精品精的特点| 精品999在线播放| 这里只有精品视频在线观看| 色婷婷av一区二区三区gif| 久久精品官网| 色先锋久久av资源部| 亚洲一区二区三区四区五区午夜| 欧美日韩一区综合| 午夜精品短视频| 欧美chengren| 91蜜桃在线免费视频| 成人免费三级在线| 成人av电影在线观看| 国产91精品在线观看| 国产成人综合亚洲91猫咪| 激情综合色综合久久| 国产一区啦啦啦在线观看| 狠狠狠色丁香婷婷综合久久五月| 麻豆精品一区二区三区| 国内精品写真在线观看| 国产一区二区久久| 不卡影院免费观看| 99国产精品视频免费观看| 91美女片黄在线| 欧美系列一区| 国产农村妇女精品一二区| 色综合久久久久久久久久久| 欧美性感一类影片在线播放| 91国内精品野花午夜精品 | 国产精品久久久久久久久图文区 | 午夜伊人狠狠久久| 日本不卡高清视频| 九色porny丨国产精品| 国产精品综合av一区二区国产馆| 国产精品456露脸| 懂色一区二区三区免费观看| 91同城在线观看| 亚洲精品影院| 在线精品亚洲一区二区不卡| 日韩欧美二区三区| 亚洲色欲色欲www| 爽爽淫人综合网网站 | 欧洲在线/亚洲| 精品国产伦一区二区三区免费 | 国产日韩一级二级三级| 一区二区三区中文在线观看| 日本女优在线视频一区二区 | 欧美日韩一区二区欧美激情| 日韩三级电影网址| 亚洲女与黑人做爰| 久久不见久久见中文字幕免费| 大尺度一区二区| 亚洲高清资源| 欧美久久婷婷综合色| 中文一区一区三区高中清不卡| 亚洲精品视频免费观看| 精品一区二区三区影院在线午夜| 成人av影院在线| 亚洲激情一区| 91麻豆精品国产自产在线观看一区| 国产精品乱码妇女bbbb| 免费看日韩精品| 欧美日韩国产色综合一二三四| 色菇凉天天综合网| 久久精品一区二区三区av| 五月婷婷欧美视频| 欧美日本精品| 欧美亚洲综合色| 国产精品免费看片| 国产麻豆精品在线| 狠狠色噜噜狠狠狠狠色吗综合| 色八戒一区二区三区| 中文字幕+乱码+中文字幕一区| 蜜臀av性久久久久蜜臀aⅴ四虎| 国产综合婷婷| 欧美一区二区视频在线观看2020 | 亚洲成人av一区二区三区| 牛人盗摄一区二区三区视频| 欧美精品久久久久久久久老牛影院| 国产精品美日韩| 懂色一区二区三区免费观看| 蜜桃av综合| 亚洲欧洲日产国产综合网| 成人免费视频播放| 欧美日韩精品电影| 亚洲综合图片区| 好看的日韩av电影| 久久综合九色综合97婷婷 | 伊人久久综合| 国产偷国产偷亚洲高清人白洁| 狠狠狠色丁香婷婷综合久久五月| 免费中文字幕日韩欧美| 亚洲国产精品ⅴa在线观看| 激情综合网天天干| 欧美在线色视频| 日韩精品亚洲一区二区三区免费| 在线观看福利一区| 国产精品欧美久久久久无广告| 久久99精品国产麻豆不卡| 久久高清一区| 亚洲图片欧美一区| 久久99伊人| 亚洲一二三四区| 国产日韩一区二区三区在线播放 | 午夜不卡av免费| 久久婷婷人人澡人人喊人人爽| 亚洲成人免费观看| 久久黄色网页| 石原莉奈在线亚洲二区| 狂野欧美性猛交xxxx巴西| 亚洲成a人片在线不卡一二三区| 亚洲一区影院| 日韩精品免费视频人成| 羞羞答答国产精品www一本| 一区二区三区**美女毛片| 亚洲永久免费精品| 日韩不卡一二三区| 欧美日本在线观看| 成人毛片老司机大片| 久久亚洲一级片| 国模吧视频一区| 亚洲伦理在线免费看| 99re6热在线精品视频播放速度| 亚洲柠檬福利资源导航| 国产情侣一区| 日本大胆欧美人术艺术动态| 欧美日韩一区二区三区在线| 国产麻豆欧美日韩一区| 2020国产精品| 亚洲高清在线播放| 香蕉影视欧美成人| 日韩一二三四区| 欧美亚洲不卡| 一区二区三区波多野结衣在线观看| 国产日韩欧美一区在线| 蜜臀a∨国产成人精品| 日韩精品专区在线影院重磅| 国产精品99一区二区| 天天操天天综合网| 一区视频在线看| 国产真实乱对白精彩久久| 国产中文字幕一区| 国产成人精品亚洲日本在线桃色| 寂寞少妇一区二区三区| 美腿丝袜亚洲一区| 另类中文字幕网| 麻豆91精品91久久久的内涵| 蜜桃久久久久久| 久久国产精品色| 日韩午夜小视频| 中国成人亚色综合网站| 国产伦精品一区二区三区免费迷 | 一区二区在线观看不卡| 在线观看成人免费视频| 欧美成人日韩| 日本aⅴ亚洲精品中文乱码| 国产亚洲精品久| 在线免费不卡电影| 在线观看成人av电影| 国产高清精品久久久久| 亚洲国产精品视频| 国产日韩在线不卡| 欧美午夜在线观看| 亚洲人妖在线|