最近整理Spring相關的知識點(面試必問) ,在我整理的過程當中,我發現本身對Spring的理解有點朦朧,由於在平時咱們接受的是Spring單個的知識點或者知道但沒有代碼的支持全部有點朦朧,因此我就把Spring知識點從總體而後往局部,到最後一個一個知識點拎出來,我想有不少的朋友或者是初學的朋友和我同樣對Spring有點朦朧,因此我分享出來,寫的不徹底和很差的歡迎指出java
spring是一個開源框架,spring爲簡化企業級開發而生,使用spring可使簡單的java bean 實現之前只有EJG才能實現的功能。web
Spring是一個輕量級的控制反轉(IoC)和麪向切面(AOP)的容器框架。面試
◆ 輕量——從大小與開銷兩方面而言Spring都是輕量的。完整的Spring框架能夠在一個大小隻有1MB多的JAR文件裏發佈。並 且Spring所需的處理開銷也是微不足道的。此外,Spring是非侵入式的:典型地,Spring應用中的對象不依賴於Spring的特定類。 spring
◆ 控制反轉——Spring經過一種稱做控制反轉(IoC)的技術促進了鬆耦 合。當應用了IoC,一個對象依賴的其它對象會經過被動的方式傳遞進來,而不是這個對象本身建立或者查找依賴對象。你能夠認爲IoC與JNDI相反——不 是對象從容器中查找依賴,而是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。 sql
◆ 面向切面——Spring提供了面向切面編程的豐富支持,容許經過分離應用的 業務邏輯與系統級服務(例如審計(auditing)和事務()管理)進行內聚性的開發。應用對象只實現它們應該作的——完成業務邏輯——僅此而已。它們 並不負責(甚至是意識)其它的系統級關注點,例如日誌或事務支持。 數據庫
◆ 容器——Spring包含並管理應用對象的配置和生命週期,在這個意義上它是 一種容器,你能夠配置你的每一個bean如何被建立——基於一個可配置原型(prototype),你的bean能夠建立一個單獨的實例或者每次須要時都生 成一個新的實例——以及它們是如何相互關聯的。然而,Spring不該該被混同於傳統的重量級的EJB容器,它們常常是龐大與笨重的,難以使用。 編程
◆ 框架——Spring能夠將簡單的組件配置、組合成爲複雜的應用。在Spring中,應用對象被聲明式地組合,典型地是在一個XML文件裏。 Spring也提供了不少基礎功能(事務管理、持久化框架集成等等),將應用邏輯的開發留給了你。設計模式
◆Spring能有效地組織你的中間層對象,不管你是否選擇使用了EJB。若是你僅僅使用了Struts或其餘的包含了J2EE特有APIs的 framework,你會發現Spring關注了遺留下的問題,。 緩存
◆Spring能消除在許多工程上對Singleton的過多使用。根據個人經驗,這是一個主要的問題,它減小了系統的可測試性和麪向對象特性。 安全
◆Spring能消除使用各類各樣格式的屬性定製文件的須要,在整個應用和工程中,可經過一種 一致的方法來進行配置。曾經感到迷惑,一個特定類要查找迷幻般的屬性關鍵字或系統屬性,爲此不得不讀Javadoc乃至源編碼嗎?有了Spring,你可 很簡單地看到類的JavaBean屬性。倒置控制的使用(在下面討論)幫助完成這種簡化。
◆Spring能經過接口而不是類促進好的編程習慣,減小編程代價到幾乎爲零。
◆Spring被設計爲讓使用它建立的應用盡量少的依賴於他的APIs。在Spring應用中的大多數業務對象沒有依賴於Spring。
◆使用Spring構建的應用程序易於單元測試。
◆Spring能使EJB的使用成爲一個實現選擇,而不是應用架構的必然選擇。你能選擇用POJOs或local EJBs來實現業務接口,卻不會影響調用代碼。
◆Spring幫助你解決許多問題而無需使用EJB。Spring能提供一種EJB的替換物,它們適於許多web應用。例如,Spring能使用 AOP提供聲明性事務而不經過使用EJB容器,若是你僅僅須要與單個的數據庫打交道,甚至不須要JTA實現。
■Spring爲數據存取提供了一致的框架,不管是使用JDBC或O/R mapping產品(如Hibernate)。
Spring確實使你能經過最簡單可行的解決辦法解決你的問題。這些特性是有很大價值的。
總結起來,Spring有以下優勢:
◆低侵入式設計,代碼污染極低
◆ 獨立於各類應用服務器,能夠真正實現Write Once,Run Anywhere的承諾
◆Spring的DI機制下降了業務對象替換的複雜性
◆Spring並不徹底依賴於Spring,開發者可自由選用Spring框架的部分或所有
在此我向你們推薦一個架構學習交流羣。交流學習羣號:575745314 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多
spring中的核心類有那些,各有什麼做用
BeanFactory:產生一個新的實例,能夠實現單例模式
BeanWrapper:提供統一的get及set方法
ApplicationContext:提供框架的實現,包括BeanFactory的全部功能
A:ApplicationContextAware接口
當一個類須要獲取ApplicationContext實例時,可讓該類實現ApplicationContextAware接口。
B:ApplicationEvent抽象類
當須要建立自定義事件時,能夠新建一個繼承自ApplicationEvent抽象類的類。
C:ApplicationListener接口
當須要監聽自定義事件時,能夠新建一個實現ApplicationListener接口的類,並將該類配置到Spring容器中。
D:BeanNameAware接口
當bean須要獲取自身在容器中的id/name時,能夠實現BeanNameAware接口。
E:InitializingBean接口
當須要在bean的所有屬性設置成功後作些特殊的處理,可讓該bean實現InitializingBean接口。
效果等同於bean的init-method屬性的使用或者@PostContsuct註解的使用。
三種方式的執行順序:先註解,而後執行InitializingBean接口中定義的方法,最後執行init-method屬性指定的方法。
F:DisposableBean接口
當須要在bean銷燬以前作些特殊的處理,可讓該bean實現DisposableBean接口。
效果等同於bean的destroy-method屬性的使用或者@PreDestory註解的使用。
三種方式的執行順序:先註解,而後執行DisposableBean接口中定義的方法,最後執行destroy-method屬性指定的方法。
G:BeanPostProcessor接口
當須要對受管bean進行預處理時,能夠新建一個實現BeanPostProcessor接口的類,並將該類配置到Spring容器中。
H:BeanFactoryPostProcessor接口
當須要對Bean工廠進行預處理時,能夠新建一個實現BeanFactoryPostProcessor接口的類,並將該類配置到Spring容器中。
事務管理的方式:編程型和聲明型,spring推薦使用後一種方式
聲明型事務管理的優點很是明顯:代碼中無需關於關注事務邏輯,讓Spring聲明式事務管理負責事務邏輯,聲明式事務管理無需與具體的事務邏輯耦 合,能夠方便地在不一樣事務邏輯之間切換。
依賴注入DI是一個程序設計模式和架構模型, 一些時候也稱做控制反轉,儘管在技術上來說,依賴注入是一個IOC的特殊實現,依賴注入是指一個對象應用另一個對象來提供一個特殊的能力,例如:把一個 數據庫鏈接已參數的形式傳到一個對象的結構方法裏面而不是在那個對象內部自行建立一個鏈接。控制反轉和依賴注入的基本思想就是把類的依賴從類內部轉化到外 部以減小依賴
應用控制反轉,對象在被建立的時候,由一個調控系統內全部對象的外界實體,將其所依賴的對象的引用,傳遞給它。也能夠說,依賴被注入到對象中。所 以,控制反轉是,關於一個對象如何獲取他所依賴的對象的引用,這個責任的反轉。
面向切面編程(AOP)提供另一種角度來思考程序結構,經過這種方式彌補了面向對象編程(OOP)的不足,除了類(classes)之外,AOP提供了切面。切面對關注點進行模塊化,例如橫切多個類型和對象的事務管理
Spring的一個關鍵的組件就是AOP框架,能夠自由選擇是否使用AOP 提供聲明式企業服務,特別是爲了替代EJB聲明式服務。最重要的服務是聲明性事務管理,這個服務創建在Spring的抽象事物管理之上。容許用戶實現自定義切面,用AOP來完善OOP的使用,能夠把Spring AOP看做是對Spring的一種加強
切面(Aspect): 一個關注點的模塊化,這個關注點可能會橫切多個對象。事務管理是J2EE應用中一個關於橫切關注點的很好的例子。 在Spring AOP中,切面可使用通用類(基於模式的風格) 或者在普通類中以 @Aspect 註解(@AspectJ風格)來實現。
鏈接點(Joinpoint): 在程序執行過程當中某個特定的點,好比某方法調用的時候或者處理異常的時候。 在Spring AOP中,一個鏈接點 老是 表明一個方法的執行。 經過聲明一個org.aspectj.lang.JoinPoint類型的參數可使通知(Advice)的主體部分得到鏈接點信息。
通知(Advice): 在切面的某個特定的鏈接點(Joinpoint)上執行的動做。通知有各類類型,其中包括「around」、「before」和「after」等通知。 通知的類型將在後面部分進行討論。許多AOP框架,包括Spring,都是以攔截器作通知模型, 並維護一個以鏈接點爲中心的攔截器鏈。
切入點(Pointcut): 匹配鏈接點(Joinpoint)的斷言。通知和一個切入點表達式關聯,並在知足這個切入點的鏈接點上運行(例如,當執行某個特定名稱的方法時)。 切入點表達式如何和鏈接點匹配是AOP的核心:Spring缺省使用AspectJ切入點語法。
引入(Introduction): (也被稱爲內部類型聲明(inter-type declaration))。聲明額外的方法或者某個類型的字段。 Spring容許引入新的接口(以及一個對應的實現)到任何被代理的對象。 例如,你可使用一個引入來使bean實現 IsModified 接口,以便簡化緩存機制。
目標對象(Target Object): 被一個或者多個切面(aspect)所通知(advise)的對象。也有人把它叫作 被通知(advised) 對象。 既然Spring AOP是經過運行時代理實現的,這個對象永遠是一個 被代理(proxied) 對象。
AOP代理(AOP Proxy): AOP框架建立的對象,用來實現切面契約(aspect contract)(包括通知方法執行等功能)。 在Spring中,AOP代理能夠是JDK動態代理或者CGLIB代理。 注意:Spring 2.0最新引入的基於模式(schema-based)風格和@AspectJ註解風格的切面聲明,對於使用這些風格的用戶來講,代理的建立是透明的。
織入(Weaving): 把切面(aspect)鏈接到其它的應用程序類型或者對象上,並建立一個被通知(advised)的對象。 這些能夠在編譯時(例如使用AspectJ編譯器),類加載時和運行時完成。 Spring和其餘純Java AOP框架同樣,在運行時完成織入。
通知的類型:
前置通知(Before advice): 在某鏈接點(join point)以前執行的通知,但這個通知不能阻止鏈接點前的執行(除非它拋出一個異常)。
返回後通知(After returning advice): 在某鏈接點(join point)正常完成後執行的通知:例如,一個方法沒有拋出任何異常,正常返回。
拋出異常後通知(After throwing advice): 在方法拋出異常退出時執行的通知。
後通知(After (finally) advice): 當某鏈接點退出的時候執行的通知(不管是正常返回仍是異常退出)。
環繞通知(Around Advice): 包圍一個鏈接點(join point)的通知,如方法調用。這是最強大的一種通知類型。 環繞通知能夠在方法調用先後完成自定義的行爲。它也會選擇是否繼續執行鏈接點或直接返回它們本身的返回值或拋出異常來結束執行。
環繞通知是最經常使用的一種通知類型。大部分基於攔截的AOP框架,例如Nanning和JBoss4,都只提供環繞通知。
切入點(pointcut)和鏈接點(join point)匹配的概念是AOP的關鍵,這使得AOP不一樣於其它僅僅提供攔截功能的舊技術。 切入點使得定位通知(advice)可獨立於OO層次。 例如,一個提供聲明式事務管理的around通知能夠被應用到一組橫跨多個對象中的方法上(例如服務層的全部業務操做)。
(1) bean定義
在配置文件裏面用<bean></bean>來進行定義。
(2) bean初始化
有兩種方式初始化:
A.在配置文件中經過指定init-method屬性來完成
B.實現org.springframwork.beans.factory.InitializingBean接口
(3) bean調用
有三種方式能夠獲得bean實例,並進行調用
(4) bean銷燬
銷燬有兩種方式
A.使用配置文件指定的destroy-method屬性
B.實現org.springframwork.bean.factory.DisposeableBean接口
singleton
當一個bean的做用域爲singleton, 那麼Spring IoC容器中只會存在一個共享的bean實例,而且全部對bean的請求,只要id與該bean定義相匹配,則只會返回bean的同一實例。
prototype
Prototype做用域的bean會致使在每次對該bean請求(將其注入到另外一個bean中,或者以程序的方式調用容器的getBean() 方法)時都會建立一個新的bean實例。根據經驗,對全部有狀態的bean應該使用prototype做用域,而對無狀態的bean則應該使用 singleton做用域
request
在一次HTTP請求中,一個bean定義對應一個實例;即每次HTTP請求將會有各自的bean實例, 它們依據某個bean定義建立而成。該做用 域僅在基於web的Spring ApplicationContext情形下有效。
session
在一個HTTP Session中,一個bean定義對應一個實例。該做用域僅在基於web的Spring
ApplicationContext情形下有效。
global session
在一個全局的HTTP Session中,一個bean定義對應一個實例。典型狀況下,僅在使用portlet
context的時候有效。該做用域僅在基於 web的Spring ApplicationContext情形下有效。
Bean的初始化方式有哪些
有兩種方式初始化Bean。
一、在配置文檔中經過指定init-method 屬性來完成
在Bean的類中實現一個初始化Bean屬性的方法,如init(),如:
public class HelloWorld{
public String msg=null;
public Date date=null;
public void init() {
msg=」HelloWorld」;
date=new Date();
}
……
}
而後,在配置文件中設置init-mothod屬性:
<bean id=」HelloWorld」 class=」com.pqf.beans.HelloWorld」 init-mothod=」init」 >
</bean>
二、實現 org.springframwork.beans.factory.InitializingBean接口
Bean實現InitializingBean接口,而且增長 afterPropertiesSet() 方法:
public class HelloWorld implement InitializingBean {
public String msg=null;
public Date date=null;
public void afterPropertiesSet() {
msg=」向全世界問好!」;
date=new Date();
}
……
}
那麼,當這個Bean的全部屬性被Spring的BeanFactory設置完後,會自動調用afterPropertiesSet()方法對 Bean進行初始化,因而,配置文件就不用指定 init-method屬性了。
有三種方式能夠獲得Bean並進行調用:
一、使用BeanWrapper
HelloWorld hw=new HelloWorld();
BeanWrapper bw=new BeanWrapperImpl(hw);
bw.setPropertyvalue(」msg」,」HelloWorld」);
system.out.println(bw.getPropertyCalue(」msg」));
二、使用BeanFactory
InputStream is=new FileInputStream(」config.xml」);
XmlBeanFactory factory=new XmlBeanFactory(is);
HelloWorld hw=(HelloWorld) factory.getBean(」HelloWorld」);
system.out.println(hw.getMsg());
三、使用ApplicationConttext
ApplicationContext actx=new FleSystemXmlApplicationContext(」config.xml」);
HelloWorld hw=(HelloWorld) actx.getBean(」HelloWorld」);
System.out.println(hw.getMsg());
一、使用配置文件中的 destory-method 屬性
與初始化屬性 init-methods相似,在Bean的類中實現一個撤銷Bean的方法,而後在配置文件中經過 **destory-method指定,那麼當bean銷燬時,Spring將自動調用指定的銷燬方法。
二、實現 org.springframwork.bean.factory.DisposebleBean接口**
若是實現了DisposebleBean接口,那麼Spring將自動調用bean中的Destory方法進行銷燬,因此,Bean中必須提供 Destory方法。
事務就是對一系列的數據庫操做(好比插入多條數據)進行統一的提交或回滾操做,若是插入成功,那麼一塊兒成功,若是中間有一條出現異常,那麼回滾之 前的全部操做。
這樣能夠防止出現髒數據,防止數據庫數據出現問題。
開發中爲了不這種狀況通常都會進行事務管理。Spring中也有本身的事務管理機制,通常是使用TransactionMananger進行管 理,能夠經過Spring的注入來完成此功能。
spring提供了幾個關於事務處理的類:
TransactionDefinition //事務屬性定義
TranscationStatus //表明了當前的事務,能夠提交,回滾。
PlatformTransactionManager這個是spring提供的用於管理事務的基礎接口,其下有一個實現的抽象類 AbstractPlatformTransactionManager,咱們使用的事務管理類例如 DataSourceTransactionManager等都是這個類的子類。
通常事務定義步驟:
TransactionDefinition td = new TransactionDefinition();
TransactionStatus ts = transactionManager.getTransaction(td);
try
{ //do sth
transactionManager.commit(ts);
}
catch(Exception e){transactionManager.rollback(ts);}
spring提供的事務管理能夠分爲兩類:編程式的和聲明式的。編程式的,比較靈活,可是代碼量大,存在重複的代碼比較多;聲明式的比編程式的更 靈活。
編程式主要使用transactionTemplate。省略了部分的提交,回滾,一系列的事務對象定義,需注入事務管理對象.
void add(){
transactionTemplate.execute( new TransactionCallback(){
pulic Object doInTransaction(TransactionStatus ts)
{ //do sth}
}
}
聲明式:
使用TransactionProxyFactoryBean:
PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED,readOnly
圍繞Poxy的動態代理 可以自動的提交和回滾事務
org.springframework.transaction.interceptor.TransactionProxyFactoryBean
PROPAGATION_REQUIRED–支持當前事務,若是當前沒有事務,就新建一個事務。這是最多見的選擇。
PROPAGATION_SUPPORTS–支持當前事務,若是當前沒有事務,就以非事務方式執行。
PROPAGATION_MANDATORY–支持當前事務,若是當前沒有事務,就拋出異常。
PROPAGATION_REQUIRES_NEW–新建事務,若是當前存在事務,把當前事務掛起。
PROPAGATION_NOT_SUPPORTED–以非事務方式執行操做,若是當前存在事務,就把當前事務掛起。
PROPAGATION_NEVER–以非事務方式執行,若是當前存在事務,則拋出異常。
PROPAGATION_NESTED–若是當前存在事務,則在嵌套事務內執行。若是當前沒有事務,則進行與 PROPAGATION_REQUIRED相似的操做。
在此我向你們推薦一個架構學習交流羣。交流學習羣號:575745314 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多
使用」org.springframework.jdbc.datasource.DriverManagerDataSource」數據源來配置數據庫驅動。示例以下:
<bean id=」dataSource」>
<property name=」driverClassName」> <value>org.hsqldb.jdbcDriver</value> </property> <property name=」url」> <value>jdbc:hsqldb:db/appfuse</value> </property> <property name=」username」><value>sa</value></property> <property name=」password」><value></value></property>
</bean>
ContextLoaderListener是一個ServletContextListener, 它在你的web應用啓動的時候初始化。缺省狀況下, 它會在WEB-INF/applicationContext.xml文件找Spring的配置。 你能夠經過定義一個<context-param>元素名字爲」contextConfigLocation」來改變Spring配置文件的 位置。示例以下:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/xyz.xml</param-value>
</context-param>
</listener-class>
</listener>
在web.xml中加入以下同容,在啓動web服務器時加載/WEB-INF/applicationContext.xml中的內容。
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
經過以下類獲得ApplicationContext實例
WebApplicationContextUtils.getWebApplicationContext
添加hibernate mapping 文件到web/WEB-INF目錄下的applicationContext.xml文件裏面。示例以下:
<property name=」mappingResources」>
<list>
<value>org/appfuse/model/User.hbm.xml</value>
</list>
</property>
a. 國際化支持
b. 資源訪問:Resource rs = ctx. getResource(」classpath:config.properties」), 「file:c:/config.properties」
c. 事件傳遞:經過實現ApplicationContextAware接口
FileSystemXmlApplicationContext:從文件系統或者url指定的xml配置文件建立,參數爲配置文件名或文件名數 組
ClassPathXmlApplicationContext:從classpath的xml配置文件建立,能夠從jar包中讀取配置文件
WebApplicationContextUtils:從web應用的根目錄讀取配置文件,須要先在web.xml中配置,能夠配置監聽器或者 servlet來實現
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
這兩種方式都默認配置文件爲web-inf/applicationContext.xml,也可以使用context-param指定配置文件
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/myApplicationContext.xml</param-value>
</context-param>
國際化處理
事件傳遞
Bean自動裝配
各類不一樣應用層的Context實現
開發中基本都在使用ApplicationContext, web項目使用WebApplicationContext ,不多用到BeanFactory
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
IHelloService helloService = (IHelloService) beanFactory.getBean("helloService");
helloService.sayHello();
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
或:
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
經過以下方法取出applicationContext實例:
ApplicationContext ac=WebApplicationContextUtils.
getWebApplicationContext(this.getServletContext);
在applicationContext.xml加載一個bean
<bean id=」messageSource」
class=」org.springframework.context.support.ResourceBundleMessageSource」>
<property name=」basename」>
<value>message</value>
</property>
</bean>
? 在src目錄下建多個properties文件
? 對於非英文的要用native2ascii -encoding gb2312 源 目轉化文件相關內容
? 其命名格式是message_語言_國家。
? 頁面中的中顯示提示信息,鍵名取鍵值。
? 當給定國家,系統會自動加載對應的國家的properties信息。
? 經過applictionContext.getMessage(「鍵名」,」參數」,」區域」)取出相關的信息。
Spring使用ThreadLocal解決線程安全問題
咱們知道在通常狀況下,只有無狀態的Bean才能夠在多線程環境下共享,在Spring中,絕大部分Bean均可以聲明爲singleton做用域。就是由於Spring對一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非線程安全狀態採用ThreadLocal進行處理,讓它們也成爲線程安全的狀態,由於有狀態的Bean就能夠在多線程中共享了。
ThreadLocal和線程同步機制都是爲了解決多線程中相同變量的訪問衝突問題。
在同步機制中,經過對象的鎖機制保證同一時間只有一個線程訪問變量。這時該變量是多個線程共享的,使用同步機制要求程序慎密地分析何時對變量進行讀寫,何時須要鎖定某個對象,何時釋放對象鎖等繁雜的問題,程序設計和編寫難度相對較大。
而ThreadLocal則從另外一個角度來解決多線程的併發訪問。ThreadLocal會爲每個線程提供一個獨立的變量副本,從而隔離了多個線程對數據的訪問衝突。由於每個線程都擁有本身的變量副本,從而也就沒有必要對該變量進行同步了。ThreadLocal提供了線程安全的共享對象,在編寫多線程代碼時,能夠把不安全的變量封裝進ThreadLocal。
因爲ThreadLocal中能夠持有任何類型的對象,低版本JDK所提供的get()返回的是Object對象,須要強制類型轉換。但JDK5.0經過泛型很好的解決了這個問題,在必定程度地簡化ThreadLocal的使用。
歸納起來講,對於多線程資源共享的問題,同步機制採用了「以時間換空間」的方式,而ThreadLocal採用了「以空間換時間」的方式。前者僅提供一份變量,讓不一樣的線程排隊訪問,然後者爲每個線程都提供了一份變量,所以能夠同時訪問而互不影響。
在此我向你們推薦一個架構學習交流羣。交流學習羣號:575745314 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多
使用 BeanFactory 從 xml配置文件加載bean:
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class XmlConfigWithBeanFactory {
public static void main(String[] args) {
XmlBeanFactory factory = new XmlBeanFactory(new FileSystemRe
"build/beans.xml"));
}
}
使用 ApplicationConText 從xml 配置文件加載 bean:
public class XmlConfigWithApplication{
public static void main(String[] args){
ApplicationContext application =
new ClassPathXmlApplicationContext(beans.xml"));
application.getBean("BeanName");
}
}
簡而言之,BeanFactory 提供了配置框架和基本的功能, 而ApplicationContext 爲它增長了更強的功能,這些功能中的一些或許更加接近J2EE 而且圍繞企業級應用。通常來講,ApplicationContext是 BeanFactory 的徹底超集, 任何 BeanFactory 功能和行爲的描述也一樣被認爲適用於ApplicationContext
相對於 BeanFactory 而言,ApplicationContext 提供瞭如下擴展功能.
(a) 國際化支持
(b) 資源訪問
(c) 事件傳播
(d) 多實例加載