国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Spring奇技淫巧之擴展點的應用

開發(fā) 架構(gòu)
bean生命周期的最后一個擴展點,該方法用于執(zhí)行一些bean銷毀前的準備工作,比如將當前bean持有的一些資源釋放掉。

[[392369]]

本文轉(zhuǎn)載自微信公眾號「月伴飛魚」,作者日常加油站。轉(zhuǎn)載本文請聯(lián)系月伴飛魚公眾號。  

最近在看公司項目和中間件的時候,看到一些Spring擴展點的使用,寫篇文章學習下,對大家之后看源碼都有幫助

「首先先介紹下Bean的生命周期」

我們知道Bean的生命周期分為幾個主干流程

  • Bean(單例非懶加載)的實例化階段
  • Bean的屬性注入階段
  • Bean的初始化階段
  • Bean的銷毀階段

下面是整個Spring容器的啟動流程,可以看到除了上述幾個主干流程外,Spring還提供了很多擴展點

下面詳細介紹下Spring的常見的擴展點

Spring常見擴展點

「BeanFactoryPostProcessor#postProcessBeanFactory」

有時候整個項目工程中bean的數(shù)量有上百個,而大部分單測依賴都是整個工程的xml,導致單測執(zhí)行時需要很長時間(大部分時間耗費在xml中數(shù)百個單例非懶加載的bean的實例化及初始化過程)

解決方法:利用Spring提供的擴展點將xml中的bean設置為懶加載模式,省去了Bean的實例化與初始化時間

  1. public class LazyBeanFactoryProcessor implements BeanFactoryPostProcessor { 
  2.     @Override 
  3.     public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 
  4.         DefaultListableBeanFactory fac = (DefaultListableBeanFactory) beanFactory; 
  5.         Map<String, AbstractBeanDefinition> map = (Map<String, AbstractBeanDefinition>) ReflectionTestUtils.getField(fac, "beanDefinitionMap"); 
  6.         for (Map.Entry<String, AbstractBeanDefinition> entry : map.entrySet()) { 
  7.             //設置為懶加載 
  8.             entry.getValue().setLazyInit(true); 
  9.         } 
  10.     } 

「InstantiationAwareBeanPostProcessor#postProcessPropertyValues」

非常規(guī)的配置項比如

  1. <context:component-scan base-package="com.zhou" /> 

Spring提供了與之對應的特殊解析器

正是通過這些特殊的解析器才使得對應的配置項能夠生效

而針對這個特殊配置的解析器為 ComponentScanBeanDefinitionParser

在這個解析器的解析方法中,注冊了很多特殊的Bean

  1. public BeanDefinition parse(Element element, ParserContext parserContext) { 
  2.   //... 
  3.   registerComponents(parserContext.getReaderContext(), beanDefinitions, element); 
  4.     //... 
  5.   return null
  1. public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( 
  2.    BeanDefinitionRegistry registry, Object source) { 
  3.  
  4.   Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4); 
  5.   //... 
  6.     //@Autowire 
  7.   if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { 
  8.    RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); 
  9.    def.setSource(source); 
  10.    beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); 
  11.   } 
  12.  
  13.   // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor. 
  14.    //@Resource 
  15.   if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { 
  16.       //特殊的Bean 
  17.    RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); 
  18.    def.setSource(source); 
  19.    beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); 
  20.   } 
  21.   //... 
  22.   return beanDefs; 
  23.  } 

以@Resource為例,看看這個特殊的bean做了什么

  1. public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor 
  2.   implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable { 
  3.       
  4.       public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds,  
  5.       Object bean, String beanName) throws BeansException { 
  6.           InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass()); 
  7.           try { 
  8.             //屬性注入 
  9.             metadata.inject(bean, beanName, pvs); 
  10.           } 
  11.           catch (Throwable ex) { 
  12.             throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex); 
  13.           } 
  14.           return pvs; 
  15.     } 
  16.      

我們看到在postProcessPropertyValues方法中,進行了屬性注入

「invokeAware」

實現(xiàn)BeanFactoryAware接口的類,會由容器執(zhí)行setBeanFactory方法將當前的容器BeanFactory注入到類中

  1. @Bean 
  2. class BeanFactoryHolder implements BeanFactoryAware{ 
  3.     
  4.     private static BeanFactory beanFactory; 
  5.      
  6.     public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 
  7.         this.beanFactory = beanFactory; 
  8.     } 

「BeanPostProcessor#postProcessBeforeInitialization」

實現(xiàn)ApplicationContextAware接口的類,會由容器執(zhí)行setApplicationContext方法將當前的容器applicationContext注入到類中

  1. @Bean 
  2. class ApplicationContextAwareProcessor implements BeanPostProcessor { 
  3.  
  4.     private final ConfigurableApplicationContext applicationContext; 
  5.  
  6.     public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) { 
  7.       this.applicationContext = applicationContext; 
  8.     } 
  9.  
  10.     @Override 
  11.     public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { 
  12.       //... 
  13.       invokeAwareInterfaces(bean); 
  14.       return bean; 
  15.     } 
  16.  
  17.     private void invokeAwareInterfaces(Object bean) { 
  18.         if (bean instanceof ApplicationContextAware) { 
  19.           ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); 
  20.         } 
  21.     } 

我們看到是在BeanPostProcessor的postProcessBeforeInitialization中進行了setApplicationContext方法的調(diào)用

  1. class ApplicationContextHolder implements ApplicationContextAware{ 
  2.     
  3.     private static ApplicationContext applicationContext; 
  4.      
  5.     public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
  6.         this.applicationContext = applicationContext; 
  7.     } 

「afterPropertySet()和init-method」

目前很多Java中間件都是基本Spring Framework搭建的,而這些中間件經(jīng)常把入口放到afterPropertySet或者自定義的init中

「BeanPostProcessor#postProcessAfterInitialization」

熟悉aop的同學應該知道,aop底層是通過動態(tài)代理實現(xiàn)的

當配置了時候,默認開啟aop功能,相應地調(diào)用方需要被aop織入的對象也需要替換為動態(tài)代理對象

不知道大家有沒有思考過動態(tài)代理是如何「在調(diào)用方無感知情況下替換原始對象」的?

根據(jù)上文的講解,我們知道:

  1. <aop:aspectj-autoproxy/> 

Spring也提供了特殊的解析器,和其他的解析器類似,在核心的parse方法中注冊了特殊的bean

這里是一個BeanPostProcessor類型的bean

  1. class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser { 
  2.  @Override 
  3.  public BeanDefinition parse(Element element, ParserContext parserContext) { 
  4.     //注冊特殊的bean 
  5.   AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element); 
  6.   extendBeanDefinition(element, parserContext); 
  7.   return null
  8.     } 

將于當前bean對應的動態(tài)代理對象返回即可,該過程對調(diào)用方全部透明

  1. public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator { 
  2.   public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 
  3.         if (bean != null) { 
  4.           Object cacheKey = getCacheKey(bean.getClass(), beanName); 
  5.           if (!this.earlyProxyReferences.containsKey(cacheKey)) { 
  6.             //如果該類需要被代理,返回動態(tài)代理對象;反之,返回原對象 
  7.             return wrapIfNecessary(bean, beanName, cacheKey); 
  8.           } 
  9.         } 
  10.         return bean; 
  11.  } 

正是利用Spring的這個擴展點實現(xiàn)了動態(tài)代理對象的替換

「destroy()和destroy-method」

bean生命周期的最后一個擴展點,該方法用于執(zhí)行一些bean銷毀前的準備工作,比如將當前bean持有的一些資源釋放掉

 

責任編輯:武曉燕 來源: 月伴飛魚
相關(guān)推薦

2020-05-20 19:38:11

前端js調(diào)試工具

2022-01-07 14:50:46

VS CodeLinux代碼

2017-08-18 13:30:01

前端CSS布局奇技

2023-06-26 08:05:36

2017-10-24 13:42:55

流氓App安卓Google

2021-03-30 07:47:46

SVG 濾鏡 CSS技巧

2020-11-26 11:45:31

Python繪圖代碼

2022-09-30 12:55:14

Linux筆記

2022-04-21 15:00:53

LinuxShell

2023-09-19 08:03:50

rebase?merge

2015-04-13 13:21:45

JavaScript JavaScript

2021-02-25 09:19:11

LinuxAppimage命令

2021-05-18 13:05:31

LinuxRust復用器

2021-06-07 12:20:14

LinuxASCII命令

2019-04-25 13:10:04

Java 8Stream API編程語言

2022-04-24 16:00:15

LinuxLinux命令ls命令

2024-11-28 09:21:00

Python字符串代碼

2021-05-07 13:56:13

Linux器監(jiān)視服務器

2021-05-31 11:45:37

LinuxRustShell

2023-09-28 08:49:41

springBean
點贊
收藏

51CTO技術(shù)棧公眾號

国产尤物91| 欧美成年人网站| 久久夜色精品亚洲噜噜国产mv| 国产精品igao视频| 日韩精品第一页| 亚洲一级片网站| sm久久捆绑调教精品一区| 中文字幕在线观看第三页| 在线观看av片| www.成人| 欧美一级一区| 成人欧美一区二区三区黑人麻豆| 欧美一区二区三区电影| 欧美黑人国产人伦爽爽爽| 看欧美日韩国产| 91精品久久久久久9s密挑| gogo大尺度成人免费视频| 日韩电影免费一区| 久久尤物电影视频在线观看| 亚洲第一精品夜夜躁人人爽| 欧美自拍视频在线观看| 国产原创中文在线观看| 香蕉视频在线播放| 综合激情久久| av影院午夜一区| 一本一道久久a久久精品 | 亚洲777理论| 久久久久久亚洲精品中文字幕| 在线一区高清| 精精国产xxxx视频在线中文版| 欧美女优在线视频| 国产成人精品免费在线| 精品成人a区在线观看| 国内外成人免费视频| 国产青草视频在线观看| 激情五月宗合网| free性m.freesex欧美| 97视频在线观看视频免费视频| 一区二区三区小说| 精品无人区太爽高潮在线播放 | 一女被多男玩喷潮视频| 麻豆网在线观看| 色喇叭免费久久综合网| 亚洲人成网站影音先锋播放| 不卡中文字幕av| av网站手机在线观看| 成人黄色网址| 美女视频免费一区| 久久亚洲精品成人| 日韩女优人人人人射在线视频| 色综合久久天天综线观看| 奇米四色中文综合久久| 国产精品久久久久久久久久久新郎 | 最近97中文超碰在线| 人妖一区二区三区| 国产精品久久久久一区| 久久福利网址导航| 不卡的av中文字幕| 精品一区二区三区中文字幕老牛| 欧美1区视频| 色偷偷久久一区二区三区| 国产精品久久国产三级国电话系列 | 97人人精品| 精品福利免费观看| 亚洲va男人天堂| 中文字幕在线三区| 亚洲三级免费| 欧美zozo另类异族| 国产在线观看欧美| 久久男人av| 欧美日韩国产不卡| 亚洲在线观看视频| 天天色天天射天天综合网| 亚洲在线黄色| 正在播放欧美视频| 国产激情二区| 亚洲女同同性videoxma| 99热精品在线观看| 精品久久久三级丝袜| 国产免费成人在线| 年轻的保姆91精品| 色婷婷综合久久久中文字幕| 鲁鲁狠狠狠7777一区二区| 成人国产精品| 欧洲一区在线观看| 91av俱乐部| 午夜亚洲精品| 日本高清视频精品| 日本孕妇大胆孕交无码| 亚洲色图第一区| 影音先锋欧美在线| 成人另类视频| 成人18视频日本| 91在线观看免费高清完整版在线观看 | 中文字幕欧美视频在线| 最近最新中文字幕在线| 亚洲一区免费| 7m精品福利视频导航| 91超碰在线免费| 亚洲成人动漫av| 视频在线观看成人| 你懂的视频一区二区| 欧美精品少妇videofree| 三级视频在线播放| 久久网站最新地址| 在线观看免费91| 亚洲字幕久久| 日本韩国欧美精品大片卡二| 国产精品伦一区二区| 在线影院国内精品| 四虎精品欧美一区二区免费| 欧美在线精品一区| 国产成人91久久精品| 在线观看亚洲精品福利片| 日韩精品福利在线| 欧洲伦理片一区 二区 三区| 久久99国产乱子伦精品免费| 亚洲最大的网站| 国产精品1区| 亚洲精品国产拍免费91在线| 2024短剧网剧在线观看| 午夜精品国产更新| 欧美xxxxxxxxx59| 亚洲欧美日韩国产综合在线| 久久精品免费一区二区| 国产精品夜夜夜| 日韩在线观看精品| 青青青免费在线视频| 日韩欧美一区二区在线视频| 三级在线免费看| 日韩福利视频导航| 国产精品久久久久久搜索 | 麻豆精品在线视频| 中文字幕av日韩精品| 一区视频在线看| 奇门遁甲1982国语版免费观看高清| 日韩伦理精品| 欧美成人性生活| 91在线一区| 成人精品福利视频| 国产剧情在线观看一区| 国产欧亚日韩视频| 欧美日韩一视频区二区| 国产欧美在线一区二区| 日韩av电影天堂| 欧美亚洲国产成人| 国产精品色哟哟| xxav视频| 欧美卡1卡2卡| 精品欧美一区二区三区在线观看| 久久精品国产一区| 狼人天天伊人久久| 4k岛国日韩精品**专区| 国产中文一区| 91在线视频九色| 日韩精品一二三四| 四虎一区二区| av网站免费线看精品| 三级免费网站| 日韩午夜av电影| 无人区在线高清完整免费版 一区二| 亚洲网址你懂得| 国产精选一区| 91久久精品国产| 欧州一区二区| 免费在线成人av| 99久久精品国产毛片| 国产专区在线视频| 国产精品污污网站在线观看 | 久久av最新网址| 日韩欧美亚洲天堂| 色婷婷精品大在线视频| 久久99久久久精品欧美| 91美女片黄在线观看游戏| 麻豆成人免费电影| 九九视频精品在线观看| 欧美一区 二区| 性高潮久久久久久久久| 亚洲一区二三区| 午夜伦理福利在线| 69堂成人精品视频免费| 成人福利在线看| 性xxxxfjsxxxxx欧美| 国产日韩欧美黄色| 国产亚洲精品aa午夜观看| 少妇性bbb搡bbb爽爽爽欧美| 最近2019年中文视频免费在线观看| 日韩激情在线| 日本不卡在线播放| 亚洲免费在线视频一区 二区| heyzo在线| 国产日韩一区二区| 亚洲一区二区三区四区在线观看| heyzo高清国产精品| 亚洲在线一区二区| 国产精品理伦片| 成人影院大全| 一本一道久久a久久综合精品| 欧美色综合天天久久综合精品| 韩国三级大全久久网站|