spring 源碼-context

1 spring-context 模塊概要
該模塊主要實現在spring-beans 模塊的擴展,主要對aop支持及el表達式的實現
在這里插入圖片描述
分析示例

  public static void main(String[] args){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");TestBean testBean = (TestBean) context.getBean("testBean");testBean.test();System.out.println(testBean);}
xml配置
<?xml version="1.0" encoding="UTF-8"?>
<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/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-3.2.xsd"><aop:aspectj-autoproxy proxy-target-class="false"/><bean id="testBean" class="com.xie.java.aop.TestBean"/><bean id="aspectJTest" class="com.xie.java.aop.AspectJTest"/>
</beans>

從ClassPathXmlApplicationContext 入手,先看下該類的繼承結構

在這里插入圖片描述
2 applicationcontext 初始化
從上面來看該類繼承還是非常復雜的,不管怎么樣,先從調用的地方入手

    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {this(new String[] {configLocation}, true, null);}public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {this(configLocations, true, null);}public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)throws BeansException {super(parent);//處理配置資源初始化setConfigLocations(configLocations);if (refresh) {//這是真正的核心入口refresh();}}

上面都是一些非常簡單的代碼,無需多解釋,接下來主要是看AbstractApplicationContext.refresh方法,context 絕大部分功能由AbstractApplicationContext去實現,下面是主線實現代碼,包括利用beanfactory加載beandefinitions 及實例化這些beans 以及aop的實現

    @Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//刷新前一些準備prepareRefresh();//獲得beafactory,并加載beandefinitionConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//準備一下beanfactory的信息prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.//調用beanfactoryPostProcessorsinvokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.//注冊bean processors 用于攔截bean的創建registerBeanPostProcessors(beanFactory);// Initialize message source for this context.//初始化容器消息源initMessageSource();// Initialize event multicaster for this context.//初始化事件廣播者initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.//初始化子容器其它特定beans onRefresh();// Check for listener beans and register them.//注冊監聽者registerListeners();// Instantiate all remaining (non-lazy-init) singletons.//實例化所有擁有非懶加載的單例finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.//最后一步,發布對應的事件finishRefresh();}//省略一些代碼}}
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;}@Overrideprotected final void refreshBeanFactory() throws BeansException {if (hasBeanFactory()) {destroyBeans();closeBeanFactory();}try {//創建beafactoryDefaultListableBeanFactory beanFactory = createBeanFactory();beanFactory.setSerializationId(getId());customizeBeanFactory(beanFactory);//加載beandefinitions loadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}}@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {// Create a new XmlBeanDefinitionReader for the given BeanFactory.//創建xml beandefinition readerXmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// Configure the bean definition reader with this context's// resource loading environment.beanDefinitionReader.setEnvironment(this.getEnvironment());beanDefinitionReader.setResourceLoader(this);beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));// Allow a subclass to provide custom initialization of the reader,// then proceed with actually loading the bean definitions.initBeanDefinitionReader(beanDefinitionReader);//通過xml reader 讀取xml配置文件 loadBeanDefinitions(beanDefinitionReader);}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {Resource[] configResources = getConfigResources();if (configResources != null) {reader.loadBeanDefinitions(configResources);}//獲得所有配置資源String[] configLocations = getConfigLocations();if (configLocations != null) {//正式通過xmlreader解釋xml 配置,并把解釋到的beandedinition//注冊到beanfactory里,接下來就是beans模塊已講過的了reader.loadBeanDefinitions(configLocations);}}

3 預實例化beanfactory里單例對象
接下要分析如何把上面得到的beandefinitions 進行實例化

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {//省略一大波代碼// Instantiate all remaining (non-lazy-init) singletons.//預實例化單例,beanFactory.preInstantiateSingletons();
}

獲取beanfactory里所有beanNames進行實例化

@Override
public void preInstantiateSingletons() throws BeansException {//獲得所有beanNames List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);//逐個遍歷,實例化預加載單例對象for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {//判斷要創建的實例是否為FactoryBeanif (isFactoryBean(beanName)) {final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {@Overridepublic Boolean run() {return ((SmartFactoryBean<?>) factory).isEagerInit();}}, getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}else {//開始他建實例,這塊是beans模塊內容,不再重述了getBean(beanName);}}}//這里省略一些代碼
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/249595.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/249595.shtml
英文地址,請注明出處:http://en.pswp.cn/news/249595.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

標示符和關鍵字的總結--希望別再犯錯

&#xff08;一&#xff09;Java關鍵字的表 一共50個關鍵字&#xff0c;如下表 其中絕大部分關鍵詞是Java語法發布之初就約定好的&#xff0c;少部分關鍵詞是隨Java語言發展后加入的。 strictfp JDK1.2 加入 assert JDK1.4 加入 enum JDK5.0 加入 還有少數單詞&#xff0c;目前…

歷屆試題 打印十字圖

問題描述 小明為某機構設計了一個十字型的徽標&#xff08;并非紅十字會啊&#xff09;&#xff0c;如下所示&#xff1a; ..$$$$$$$$$$$$$....$...........$..$$$.$$$$$$$$$.$$$$...$.......$...$$.$$$.$$$$$.$$$.$$.$...$...$...$.$$.$.$$$.$.$$$.$.$$.$.$...$...$.$.$$.$.$.…

Spring BeanDefinition

BeanDefinition&#xff0c;顧名思義&#xff0c;是一個對象(Bean)在Spring中描述&#xff0c;其核心類圖&#xff1a; 從類圖我們詳細了解BeanDefinition。 BeanDefinition接口繼承自BeanMetadataElement和AttributeAccessor兩個接口。 BeanMetadataElement&#xff1a;bean…

樂尚網絡:小程序商城零售行業10大新賦能

微信小程序上線以來&#xff0c;各行各業積極入場小程序&#xff0c;著手打造屬于自己的小程序生態。小程序形態多樣&#xff0c;適合你的小程序才是最好的&#xff1b;在眾多形態中&#xff0c;小程序商城可以說是零售行業的主體形態了&#xff0c;因為通過平臺直接實現交易是…

深度學習中的正則化

正則化方法有如下幾種&#xff1a; 一、參數范數懲罰 其中L2、L1參數正則化介紹與關系如下 1、L2 參數正則化 直觀解釋如下&#xff1a; 2、L1 參數正則化 二、獲取更多數據&#xff08;擴樣本&#xff09; 避免過擬合的基本方法之一是從數據源獲得更多數據&#xff0c;當訓練數…

spring uml

spring執行流程&#xff1a; 1&#xff1a; 加載spring.xml文件 2&#xff1a; 創建xml文件解析器 3&#xff1a; 獲取命名空間&#xff0c;即在spring.xml文件中的 http://www.springframework.org/schema/context 4&#xff1a; 根據命名空間找到命名空間處理器&#xff0c;在…

「造個輪子」——cicada(輕量級 WEB 框架)

前言 俗話說 「不要重復造輪子」&#xff0c;關于是否有必要不再本次討論范圍。 創建這個項目的主要目的還是提升自己&#xff0c;看看和知名類開源項目的差距以及學習優秀的開源方式。 好了&#xff0c;現在著重來談談 cicada 這個項目的核心功能。 我把他定義為一個快速、輕量…

基于owncloud構建私有云儲存網盤

注意事項&#xff1a;需要ping通外網 需要LAMP架構yum -y install httpd php php-mysql mariadb-server mariadb sqlite php-dom php-mbstring php-gd php-pdo 開啟服務[rootowncloud ~]# setenforce 0setenforce: SELinux is disabled[rootowncloud ~]# systemctl stop firewa…

Spring 源碼分析之AbstractApplicationContext源碼分析

首先我覺得分析ApplicationContext必須從它的實現類開始進行分析&#xff0c;AbstractApplicationContext我覺得是一個不錯的選擇&#xff0c;那我們就從這里開始逐一分析吧&#xff0c;首先我自己手畫了一張圖&#xff0c;作為索引吧&#xff0c;其中藍色的為類&#xff0c;紫…

[USACO15FEB]Superbull (最小生成樹)

題目鏈接 Solution 基本上就是個板子. 因為 \(n\) 很小,只有 \(2000\),所以直接暴力建圖,然后跑最小生成樹就好了. Code #include<bits/stdc.h> #define ll long long using namespace std; const int maxn2008; struct sj{int to,fr; ll w; }a[maxn*maxn]; int fa[maxn]…

Java中九大內置對象

1、Request對象 該對象封裝了用戶提交的信息&#xff0c;通過調用該對象相應的方法可以獲取封裝的信息&#xff0c;即使用該對象可以獲取用戶提交的信息。 當Request對象獲取客戶提交的漢字字符時&#xff0c;會出現亂碼問題&#xff0c;必須進行特殊處理。首先&#xff0c;…

ORACLE導出導入意外終止導致 ORACLE initialization or shutdown in progress 問題解決

由于意外情況導致 ORACLE initialization or shutdown in progress 個人理解為主要是歸檔日志出現問題&#xff0c; 首先cmd 1.sqlplus /nolog 進入sqlplus 2.connect /as sysdba 連接dba 3.shutdown normal 卸載數據庫 4.startup mount;重啟例程 5.alter database open;開…

Spring中資源的加載ResourceLoader

Spring中資源的加載是定義在ResourceLoader接口中的&#xff0c;它跟前面提到的抽象資源的關系如下&#xff1a; ResourceLoader的源碼 public interface ResourceLoader { /** Pseudo URL prefix for loading from the class path: "classpath:" */ String CLAS…

Codeforces Round #540 (Div. 3)(部分題解)

鏈接:http://codeforces.com/contest/1118 來源:Codeforces 文章目錄A. Water BuyingB. Tanya and Candies(前綴和)D1. Coffee and Coursework (Easy version)(貪心)D2. Coffee and Coursework (Hard Version)(二分)A. Water Buying 題意:用最小的花費買到剛好合適的東西.我們可…

集合一些方法陷阱

一&#xff1a;asList 數組轉ArrayList陷阱&#xff1a; asList() 源碼&#xff1a;public static <T> List<T> asList(T... a) { return new ArrayList<T>(a); } private final E[] a; ArrayList(E[] array) { if (arraynull) throw new NullPointerExcept…

java項目中的classpath

在java項目中&#xff0c;你一定碰到過classpath&#xff0c;通常情況下&#xff0c;我們是用它來指定配置/資源文件的路徑。在剛開始學習的時候&#xff0c;自己也糊里糊涂&#xff0c;但是現在&#xff0c;是時候弄清楚它到底是指什么了。 顧名思義&#xff0c;classpath就是…

C++命名空間(namespace)

在c中&#xff0c;名稱&#xff08;name&#xff09;可以是符號常量、變量、函數、結構、枚舉、類和對象等等。工程越大&#xff0c;名稱互相沖突性的可能性越大。另外使用多個廠商的類庫時&#xff0c;也可能導致名稱沖突。為了避免&#xff0c;在大規模程序的設計中&#xff…

P1556 幸福的路

題意&#xff1a;平面內有N頭牛$N\le 10$john從&#xff08;0,0&#xff09;出發&#xff0c;最后回到(0,0) 只有走到牛那里john才可以改變方向&#xff0c;否則沿著直線走 問john經過每一頭牛并且在每一頭牛出恰好改變方向一次的方案&#xff08;牛可以經過多次&#xff0c;但…

Class.getResource和ClassLoader.getResource

一案例驅動 二源碼分析 三類加載器ClassLoader 四總結 五參考 一案例驅動 最近加載文件的時候遇到了一個問題&#xff0c;很有意思&#xff01; 具體看下面案例代碼 public class TestClassLoader {public static void main(String[] args) {System.out.println(TestClassLoad…

spring-6、動態代理(cglib 與 JDK)

JDK動態代理與Cglib動態代理 JDK動態代理: 1.能夠繼承靜態代理的全部優點.并且能夠實現代碼的復用.2.動態代理可以處理一類業務.只要滿足條件 都可以通過代理對象進行處理.3.動態代理的靈活性不強.4.JDK 的動態代理要求代理者必須實現接口, , 否則不能生成代理對象. . 1 packag…