-
Spring相關(guān)知識(shí)
第一章 概述
1-1 Spring入門課程簡(jiǎn)介
SpringFrameWork
?
1-2 Spring概況
1.一個(gè)輕量的控制反轉(zhuǎn)(IoC)和面向切面(AOP)的容器框架
(1)從大小和開銷兩方面而言,Spring是輕量的
(2)通過控制反轉(zhuǎn)達(dá)到松耦合的目的
(3)提供面向切面編程的豐富支持,允許通過分離應(yīng)用的業(yè)務(wù)邏輯(如商品的入庫(kù))與系統(tǒng)級(jí)服務(wù)(如日志記錄)進(jìn)行內(nèi)聚性的開發(fā)
(4)包含并管理應(yīng)用對(duì)象的配置和生命周期,這個(gè)意義上是一種容器(容器:用來管理對(duì)象)
(5)將簡(jiǎn)單的組件配置、組合成為復(fù)雜的應(yīng)用,這個(gè)意義上是框架(框架:半成品,支持其他組件的組合)
2.Spring作用
容器、提供對(duì)多種技術(shù)的支持、AOP(事務(wù)管理、日志)、提供了眾多方便應(yīng)用的輔助類(JDBC 模板等)、對(duì)主流應(yīng)用框架(MyBatis)提供了良好的支持
3.適應(yīng)范圍
(1)構(gòu)建企業(yè)應(yīng)用(SpringMVC+Spring+MyBatis)
(2)單獨(dú)使用Bean容器進(jìn)行管理
(3)單獨(dú)使用AOP進(jìn)行切面處理
(4)其他的Spring功能,如:對(duì)消息的支持
(5)在互聯(lián)網(wǎng)中的應(yīng)用
?
1-3 Spring框架
1.框架
(1)定義:一套規(guī)范或規(guī)則,程序員在該規(guī)范或規(guī)則下工作
(2)特性:半成品,封裝了特定的處理流程和控制邏輯,成熟的、不斷升級(jí)改進(jìn)的軟件
(3)與類庫(kù)的區(qū)別:框架一般是封裝了邏輯、高內(nèi)聚的,類庫(kù)則是松散的工具組合;框架專注于某一領(lǐng)域,類庫(kù)則是更通用的
(4)為什么使用框架:軟件系統(tǒng)日趨復(fù)雜;重用度高,開發(fā)效率和質(zhì)量提高;軟件設(shè)計(jì)人員要專注于對(duì)領(lǐng)域的了解,使需求分析更充分;易于上手、快速解決問題
?
第二章 Spring IoC容器
2-1 IoC及Bean容器
1.接口
用于溝通的中介物(規(guī)范)的抽象化
對(duì)外提供一些功能,內(nèi)部的實(shí)現(xiàn)不公開
Java中,接口即聲明,聲明了哪些方法是對(duì)外公開提供的
Java8中,接口可以有方法體
?
2.面向接口編程
結(jié)構(gòu)設(shè)計(jì)中,分清層次及調(diào)用關(guān)系,每層只向外(上層)提供一組功能接口,各層間僅依賴接口而非實(shí)現(xiàn)類
接口實(shí)現(xiàn)的變動(dòng)不影響各層間的調(diào)用,這一點(diǎn)在公共服務(wù)中尤為重要
“面向接口編程”中的“接口”是用于隱層具體實(shí)現(xiàn)和實(shí)現(xiàn)多態(tài)性的組件
例子:
接口Dao,實(shí)現(xiàn)類DaoImpl,使用方法為多態(tài)Dao dao = new DaoImpl();用接口聲明,將接口的實(shí)現(xiàn)類賦值給接口,最后調(diào)方法
?
3.IoC
IoC:控制反轉(zhuǎn),控制權(quán)的轉(zhuǎn)移,應(yīng)用程序本身不負(fù)責(zé)依賴對(duì)象的創(chuàng)建和維護(hù),而是由外部容器負(fù)責(zé)創(chuàng)建和維護(hù)(住房子不是自己來建,而是找中介——中介找房子——住中介找的房子,即IoC的動(dòng)作:找IoC容器——容器返回對(duì)象——使用對(duì)象)
DI:依賴注入,是IoC的一種實(shí)現(xiàn)方式,目的是創(chuàng)建對(duì)象并組裝對(duì)象之間的關(guān)系
IoC中,所有的容器稱為Bean
?
4.Bean容器的初始化
(1)基礎(chǔ):兩個(gè)包org.springframework.beans和org.springframeword.context
BeanFactory提供配置結(jié)構(gòu)和基本功能,加載并初始化Bean
ApplicationContext是BeanFactory的子接口,保存了Bean對(duì)象并在Spring中被廣泛使用
他們都可以代表Spring容器,Spring容器是生成Bean實(shí)例的工廠,并管理Bean??????
在創(chuàng)建Spring容器的實(shí)例時(shí)(通過getBean方法),必須提供Spring容器管理的Bean的詳細(xì)配置信息,Spring的配置信息通常通過xml配置文件來設(shè)置(也可通過注解)。
在實(shí)際的應(yīng)用中,Spring容器通常是采用聲明式方式配置產(chǎn)生:即開發(fā)者只要在web.xml文件中配置一個(gè)Listener,該Listener將會(huì)負(fù)責(zé)初始化Spring容器。
實(shí)現(xiàn)BeanFactoryAware接口的Bean實(shí)例,擁有訪問BeanFactory容器的能力
就是說,ApplicationContext用來管理Bean,可以通過xml配置文件或注解的方式來將Bean注冊(cè)到ApplicationContext中
(2)初始化ApplicationContext的方式
1°本地文件
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("F:/workspace/ applicationContext.xml");
2°Classpath
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
3°Web應(yīng)用中依賴servlet或Listener
a.
<listener>
????? <listener-class>org.springframework.web.context.ContextLoaderListener<listener-class>
<listener>
b.
<servlet>
????? <servlet-name>context<servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet<servlet-class>
<load-on-startup>1<load-on-startup>
<servlet>
?
2-2 Spring注入方式
1.指在啟動(dòng)Spring容器加載bean配置的時(shí)候,完成對(duì)變量的賦值行為
常用的兩種注入方式:
設(shè)值注入
構(gòu)造注入
?
2.設(shè)值注入(即調(diào)用set方法,需要在InjectionServiceImpl類中提供set方法來獲取InjectionDAO的對(duì)象)
<bean id="injectionService" class="com.imooc.injection.serivec.InjectionServiceImpl">
????? <property name="injectionDAO" ref="injectionDAO"/>????
????? 或<property name="injectionDAO" ref="injectionDAO"></property>
</bean>
?
<bean id="injectionDAO" class="com.imooc.ioc.injection.dao.InjectionDAOImpl"></bean>
?
3.構(gòu)造注入(即調(diào)用構(gòu)造方法,需要在InjectionServiceImpl類中提供構(gòu)造方法來獲取InjectionDAO的對(duì)象)
<bean id="injectionService" class="com.imooc.injection.serivec.InjectionServiceImpl">
????? <constructor-arg name="injectionDAO" ref="injectionDAO"/>
<constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg>
</bean>
?
<bean id="injectionDAO" class="com.imooc.ioc.injection.dao.InjectionDAOImpl"></bean>
?
第三章 Spring Bean裝配(上)
主要部分:
Bean配置項(xiàng)
Bean的作用域
Bean的生命周期
Bean的自動(dòng)裝配
Resource和ResourceLoader
Bean的注解方式(對(duì)以上內(nèi)容用注解方式進(jìn)行改進(jìn))
3-1 Spring Bean裝配之Bean的配置項(xiàng)和作用域
1.Bean的配置項(xiàng)
(1)Id:Bean的唯一標(biāo)識(shí)
(2)Class:具體要實(shí)例化的類
(3)Scope:作用域(范圍)
(4)Constructor arguments:構(gòu)造器參數(shù)
(5)Properties:屬性
(6)Autowiring mode:自動(dòng)裝配模式
(7)lazy-initialization mode:懶加載模式
(8)Initialization/destruction method:初始化/銷毀方法
?
2.Bean的作用域
(1)singleton:(默認(rèn)作用域)單例,指一個(gè)Bean容器中只存在一份
(2)prototype:每次請(qǐng)求(每次使用)創(chuàng)建新的實(shí)例,destory方法不生效(因?yàn)闀?huì)自動(dòng)回收)
(3)request:每次http請(qǐng)求創(chuàng)建一個(gè)實(shí)例且僅在當(dāng)前request內(nèi)有效
(4)session:同上,每次http請(qǐng)求創(chuàng)建,當(dāng)前session內(nèi)有效(session在一個(gè)會(huì)話周期有效)
(5)global session:基于portlet的web中有效(protlet定義了global session),如果是在web中,同session(假如有多個(gè)系統(tǒng),global session跨越多個(gè)session)
?
3-2 Spring Bean裝配之Bean的生命周期
1.Bean的生命周期
定義
初始化
使用
銷毀
?
2.單一Bean初始化的兩種方式
(1)實(shí)現(xiàn)org.springframework.beans.factory.InitializingBean接口,覆蓋afterPropertiesSet方法
public class ExampleInitializingBean implements IntializingBean {
????? @Override
????? public void afterPropertiesSet() throws Exception {
?????????? //do something
}
}
(2)配置init-method
<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
public class ExampleBean {
????? public void init() {
????? //do some initialization work
}
}
?
3.單一Bean銷毀的兩種方式
(1)實(shí)現(xiàn)org.springframework.beans.factory.DisposableBean接口,覆蓋destory方法
public class ExampleDisposableBean implements DisposableBean {
????? @Override
????? public void destory() throws Exception {
?????????? //do something
}
}
(2)配置destory-method
<bean id="exampleInitBean" class="examples.ExampleBean" destory-method="cleanup"/>
public class ExampleBean {
????? public void cleanup() {
????? //do some destructiono work (like relesing polled connections)
}
}
?
4.配置全局默認(rèn)的初始化、銷毀方法(所有Bean都會(huì)調(diào)用)
在Bean的配置文件的最外層(最上層),緊接著xmlns(XML的命名空間)和xsi:schemaLocation后面,添加
default-init-method="init" default-destory-method="destory">
?
5. 優(yōu)先級(jí)
實(shí)現(xiàn)接口的方式>配置init-method和destory-method的方式
如果配置了單一Bean的初始化/銷毀方式,那么全局默認(rèn)的初始化/銷毀方式不會(huì)生效
?
3-3 Spring Bean裝配之Aware接口
1.Aware
(1)Spring中提供了一些以Aware結(jié)尾的接口,實(shí)現(xiàn)了Aware接口的Bean在被初始化之后,可以獲取相應(yīng)資源
(2)通過Aware接口,可以對(duì)Spring相應(yīng)資源進(jìn)行操作(一定要慎重)
(3)為對(duì)Spring進(jìn)行簡(jiǎn)單的擴(kuò)展提供了方便的入口
?
如:ApplicationContextAware、BeanNameAware
?
Day45(8.13)
?
3-4 Spring Bean裝配之自動(dòng)裝配(Autowiring,即自動(dòng)注入)
1.自動(dòng)裝配的類型
(1)No:不做任何操作
(2)byname:根據(jù)屬性名自動(dòng)裝配。此選項(xiàng)將檢查容器并根據(jù)名字查找與屬性完全一致的bean,并將其與屬性自動(dòng)裝配
(3)byType:如果容器中存在一個(gè)與指定屬性類型相同的bean,那么將與該屬性自動(dòng)裝配;如果存在多個(gè)該類型bean,那么拋出異常,并指出不能使用byType方式進(jìn)行自動(dòng)裝配;如果沒有找到相匹配的bean,則什么事都不發(fā)生
(4)Constructor:與byType方式類似,不同之處在于他應(yīng)用于構(gòu)造器參數(shù)。如果容器中沒有找到與構(gòu)造器參數(shù)類型一致的bean,那么拋出異常
?
2.個(gè)人理解
這種方式是:對(duì)于一個(gè)需要注入的bean,不需要在它的bean中添加property或constructor-arg配置(手動(dòng)注入),而是在xml配置文件中設(shè)置autowire來實(shí)現(xiàn)自動(dòng)注入,自動(dòng)調(diào)用setter方法或構(gòu)造方法(注意,仍然需要setter方法或構(gòu)造方法),如:
原來是:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=…
…>
<bean id="injectionService" class="com.imooc.injection.serivec.InjectionServiceImpl">
????? <property name="injectionDAO" ref="injectionDAO"/>????
</bean>
<bean id="injectionDAO" class="com.imooc.ioc.injection.dao.InjectionDAOImpl"></bean>
現(xiàn)在是:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=…
…
default-autowire="byName">
<bean id="injectionService" class="com.imooc.injection.serivec.InjectionServiceImpl"></bean>
<bean id="injectionDAO" class="com.imooc.ioc.injection.dao.InjectionDAOImpl"></bean>
?
3-5 Spring Bean裝配之Resources
1.針對(duì)于資源文件的統(tǒng)一接口(獲取資源文件)
?
2.Resources的類型
(1)UrlResource:URL對(duì)應(yīng)的資源,根據(jù)一個(gè)URL地址既可創(chuàng)建
(2)ClassPathResource:獲取類路徑下的資源文件
(3)FileSystemResource:獲取文件系統(tǒng)里面的資源
(4)ServletContextResource:ServletContext封裝的資源,用于訪問ServletContext環(huán)境下的資源
(5)InputStreamResource:針對(duì)于輸入流封裝的資源
(6)ByteArrayResource:針對(duì)于字節(jié)數(shù)組封裝的資源
?
3.Resources的加載類ResourceLoader
所有application context都實(shí)現(xiàn)了ResourceLoader接口,所以都可以用來獲取Resource實(shí)例
獲取Resource對(duì)象舉例:
(可以通過實(shí)現(xiàn)ApplicationContextAware接口)在獲取applicationContext對(duì)象后,就可以獲取資源
Resource template = applicationContext.getResource("some/resource/path/myTemplate.txt");
Resource template = applicationContext.getResource("classpath:some/resource/path/myTemplate.txt");
Resource template = applicationContext.getResource("file:/some/resource/path/myTemplate.txt");
?
4.ResourceLoader的前綴
前綴??????????? 例子
classpath:?? classpath:com/myapp/config.xml
file:??????????? file:/data/config.xml
http:????????? http://myserver/logo.png
(none):?????? /data/config.xml(此時(shí)依賴于ApplicationContext所依賴的,例如如果是classpath就是classpath)
?
第四章 Spring Bean裝配(下)
4-1 Spring Bean裝配之Bean的定義及作用域的注解實(shí)現(xiàn)
1.Classpath掃描與組件管理
(1)從Spring3.0開始,Spring JavaConfig項(xiàng)目提供了很多特性,包括使用java而不是xml定義bean,比如@Configuration、@Bean、@Import、@DependsOn
(2)Component是一個(gè)通用注解,可用于任何bean
(3)Repository、@Service、@Controller是更有針對(duì)性的注解
@Repository通常用于注解DAO類,即持久層
@Service通常用于注解Service類,即服務(wù)層
@Controller通常用于注解Controller類,即控制層(MVC)
?
2.元注解
即注解的注解,如:
@Component
public @interface Service {
????? //…
}
對(duì)于Service這個(gè)注解,可以用Component注解進(jìn)行注解
?
3.類的自動(dòng)檢測(cè)及Bean的注冊(cè)
Spring可以自動(dòng)檢測(cè)類并注冊(cè)Bean到ApplicationContext中(通過注解的方式)
?
4.<context:annotation-config/>
通過在基于xml的Spring配置如下標(biāo)簽(請(qǐng)注意:在頭文件中加上該標(biāo)簽,會(huì)同時(shí)自動(dòng)加入context命名空間)
<context:annotation-config/>,;僅會(huì)查找在同一個(gè)applicationContext中的bean注解
?
5.類的自動(dòng)檢測(cè)及Bean的注冊(cè)
(1)為了檢測(cè)類并注冊(cè)相應(yīng)的Bean,需要在文件頭中的下面添加一行(component-scan即對(duì)注解進(jìn)行掃描,如果掃描到注解對(duì)應(yīng)的類,將該類注冊(cè)到容器上;base-package是掃描該包下的類):
<context:component-scan base-package="com.service"/>
(2)<context:component-scan>包含<context:annotation-config>,通常在使用前者后,不用再使用后者(前者對(duì)類和類內(nèi)的注解進(jìn)行掃描,后者只對(duì)類內(nèi)的方法或成員變量的注解進(jìn)行掃描)
?
6.使用過濾器進(jìn)行自定義掃描
(1)默認(rèn)情況下,類被自動(dòng)發(fā)現(xiàn)并注冊(cè)bean的條件是:使用@Component、@Repository、@Service、@Controller注解或使用@Component的自定義注解
(2)可以通過過濾器修改上面的自動(dòng)發(fā)現(xiàn)行為,如:
<beans>
????? <context:component-scan base-package="org.example">
?????????? <context:include-filter type="regex"
???????????????? expression=".*Stub.*Repository"/>
?????????? <context:exclude-filter type="annotation"
???????????????? expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
</beans>
本例的xml配置忽略所有的@Repository注解并尋找所有使用"Stub"注解的類
(3)還可以使用use-default-filters="false"禁止自動(dòng)發(fā)現(xiàn)與注冊(cè)
?
7.過濾器的類型
annotation、assignable、aspectj、regex、custom
?
8.如何自定義Bean
(1)掃描過程中組件被自動(dòng)檢測(cè),那么Bean名稱是由BeanNameGenerator生成的(@Component、@Repository、@Service、@Controller都會(huì)有個(gè)name屬性用來顯示設(shè)置Bean Name),如果不顯式指定name,則用默認(rèn)生成的(默認(rèn)為首字母小寫的類名),如:
@Service("myMovieListener")
public class SimpleMovieListener {
????? //…
}
和
@Service()? //此處的name默認(rèn)為simpleMovieListener
public class SimpleMovieListener {
????? //…
}
此處的名稱相當(dāng)于xml配置文件中的id
(2)可以自定義Bean的默認(rèn)命名策略,如:
<beans>
????? <context:component-scan base-package="org.example"
?????????? name-generator="org.example.MyNameGenerator"/>
</beans>
要實(shí)現(xiàn)BeanNameGenerator接口,并一定要包含一個(gè)無參構(gòu)造器,
?
9.作用域(Scope)
(1)通常情況下自動(dòng)查找的Spring組件,其scope是singleton,Spring2.5提供了一個(gè)標(biāo)識(shí)scope的注解@Scope
@Scope("prototype")
@Repository
public class MovieFinderImpl implements MovieFinder {
????? //…
}
(2)也可以自定義scope策略,如
<beans>
????? <context:component-scan base-package="org.example"
?????????? scope-resolver="org.example.MyScopeResolver"/>
</beans>
要實(shí)現(xiàn)ScopeMetadataResolver接口并提供一個(gè)無參構(gòu)造器
?
10.代理方式(代理即代理網(wǎng)絡(luò)用戶去取得網(wǎng)絡(luò)信息)
可以使用scoped-proxy屬性指定代理,有三個(gè)值可選:no、interfaces、targetClass(目標(biāo)類),如:
<beans>
????? <context:component-scan base-package="org.example"
?????????? scoped-proxy="interfaces"/>
</beans>
?
4-2 Spring Bean裝配之Autowired注解說明-1
1.@Required
(1)Required注解適用于bean屬性的setter方法
(2)這個(gè)注解僅僅標(biāo)識(shí),受影響的bean屬性必須在配置時(shí)被填充,通過在bean定義或通過自動(dòng)裝配一個(gè)明確的屬性值如:
public class SimpleMovieListener {
????? private MovieFinder movieFinder;
?????
????? @Required
????? public void setMovieFinder(MovieFinder movieFinder) {
?????????? this.movieFinder = movieFinder;
}
//…
}
?
2.@Autowired(不需要在xml中使用autowire屬性,添加注解即可實(shí)現(xiàn)自動(dòng)注入)
個(gè)人理解:在A類的方法中需要B類的對(duì)象,要通過注入的方式實(shí)現(xiàn),最普通的方式是在xml中添加配置,也可以在xml中設(shè)置autowire屬性來自動(dòng)注入,還可以用添加注解的方式來自動(dòng)注入
(1)可以將@Autowired注解理解為“傳統(tǒng)”的setter方法,如:
private MovieFinder movieFinder;
?
@Autowired
public void setMovieFinder(MovieFinder movieFinder) {
????? this.movieFinder = movieFinder;
}
(2)也可以用于構(gòu)造器或成員變量,如:
@Autowired
private MovieCatalog movieCatalog;
?
private CustomerPreferenceDao customerPerferenceDao;
?
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
????? this. customerPreferenceDao = customerPreferenceDao;
}
(3)默認(rèn)情況下,如果找不到合適的bean,將會(huì)導(dǎo)致autowiring失敗并拋出異常,可以通過下面的方式避免:
public class SimpleMovieListener {
????? private MovieFinder movieFinder;
?????
????? @Autowired(required=false)
????? public void setMovieFinder(MovieFinder movieFinder) {
?????????? this.movieFinder = movieFinder;
}
//…
}
注意:
1°每一個(gè)類只能有一個(gè)構(gòu)造器被標(biāo)記為required=true
2°@Autowired的必要屬性,建議使用@Required來注解
?
4-3 Spring Bean裝配之Autowired注解說明-2
1.@Autowired
(1)可以使用@Autowired注解那些眾所周知的解析依賴性接口,比如:BeanFactory, ApplicationContext, Environment, ResourceLoader, ApplicationEventPublisher, MessageSource,例:
public class MovieRecommender {
????? @Autowired
????? private ApplicationContext context;
?????
????? public MovieRecommender() {
}
????? //…
}
通過注解,可以得到ApplicationContext并使用
(2)可以通過添加注解給需要該類型的數(shù)組的字段或方法,以提供ApplicationContext中的所有的特定類型的bean,
1°可以用于裝配Set,如:
private Set<MovieCatalog> movieCatalogs;
?
@Autowired
public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
????? this. movieCatalogs = movieCatalogs;
}
通過@Autowired注解后,ApplicationContext中的所有符合Set的泛型聲明的bean或其子類將會(huì)放到Set中去
2°可以用于裝配key為String的Map(key即所有Bean的id,value即Bean的對(duì)象),如:
private Map<String, MovieCatalog> movieCatalogs;
?
@Autowired
public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
????? this. movieCatalogs = movieCatalogs;
}
3°如果希望list數(shù)組有序,可以讓bean實(shí)現(xiàn)org.springframe.core.Ordered接口或使用@Order注解
如:@Order(value=1)對(duì)應(yīng)的bean,排在@Order(value=2)對(duì)應(yīng)的bean之前
(3)注意:
@Autowired注解是由Spring BeanPostProcessor處理的,所以不能在自己的BeanPostProcessor或BeanFactoryPostProcessor類型中應(yīng)用這些注解,這些類型必須通過xml或Spring的@Bean注解加載
(4)例子
定義一個(gè)接口和他的兩個(gè)實(shí)現(xiàn)類,都用@Component進(jìn)行注解(來讓Spring發(fā)現(xiàn)并注冊(cè)為bean),然后定義一個(gè)list<接口>并用@Autowired進(jìn)行注解,這樣就可以將這兩個(gè)實(shí)現(xiàn)類注入到list中
?
4-4 Spring Bean裝配之Autowired注解說明-3
1.@Qualifier
(1)定義
按類型自動(dòng)裝配時(shí),可能有多個(gè)bean實(shí)例的情況,這時(shí)可以使用Spring的@Qualifier注解來縮小范圍(或指定唯一),也可以用于指定單獨(dú)的構(gòu)造器或方法參數(shù)
可以用于注解集合類型變量
(2)使用舉例
1°用于成員變量
對(duì)成員變量用@Qualifier進(jìn)行注解,當(dāng)有多個(gè)MovieCatalog想自動(dòng)注入到bean時(shí),只將id為main的注入到bean
public class MovieRecommender {
????? @Autowired
????? @Qualifier("main")
????? private MovieCatalog movieCatalog;
}
2°用在方法中(最常用)
@public void prepare(@Qualifier("main") MovieCatalog movieCatalog, CustomerPreferenceDao customerPreferenceDao) {
????? this.movieCatalog = movieCatalog;
????? this.customerPreferenceDao = customerPreferenceDao;
}
3°在xml中使用
<bean class="example.SimpleMovieCatalog">
????? <qualifier value="main"/>
</bean>
(3)
如果通過名字進(jìn)行注解注入,主要使用的不是@Autowired(即使在技術(shù)上能夠通過@Qualifier執(zhí)行bean的名字),替代方式是使用JSR-250標(biāo)準(zhǔn)中的@Resource注解,它是通過其獨(dú)特的名稱來定義來識(shí)別特性的名稱(這是一個(gè)與所聲明的類型無關(guān)的匹配過程)
因語義差異,集合或Map類型的bean無法通過@Autowired來注入,這是因?yàn)闆]有類型匹配到這樣的bean。為這些bean使用@Resource注解,可以通過唯一名稱引用集合或Map的bean。
@Autowired適用于fields,constructors,multi-argument methods這些允許在參數(shù)級(jí)別使用@Qualifier注解縮小范圍的情況
????? @Resource適用于成員變量、只有一個(gè)參數(shù)的setter方法,所以在目標(biāo)是構(gòu)造器或一個(gè)多參數(shù)方法時(shí),最好的方式使用qualifiers
(4)定義自己的qualifier注解并使用
定義:
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre {
????? String value();
}
使用:
public class MovieRecommender {
????? @Autowired
????? @Genre("Action")
private MovieCatalog comedyCatalog;
?
@Atuowired
public void setComedyCatalog(@Genre("Comedy") MovieCatalog comedyCatalog) {
????? this.comedyCatalog = comedyCatalog;
}
}
在xml中定義
<bean class="example.SimpleMovieCatalog">
????? <qualifier type="Genre" value="Action"/>
</bean>
?
4-5 Spring Bean裝配之基于Java的容器注解說明——@Bean
1.定義
(1)Bean標(biāo)識(shí)一個(gè)用于配置和初始化一個(gè)由SpringIoC容器管理的新對(duì)象的方法,類似于XML配置文件的<bean/>
(2)可以在Spring的@Component注解的類中,使用@Bean注解任何方法(僅僅是可以)
(3)上一點(diǎn)中,通常使用的是@Configuration(即將該類當(dāng)做一個(gè)配置文件來使用)
(4)如:
@Configuration
public class AppConfig {
????? @Bean
????? public MyService myService() {
?????????? return new MyServiceImpl();
}
}
等價(jià)于
<beans>
????? <bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>
2.自定義Bean name
public class AppConfig {
????? @Bean(name="myFoo")
????? public Foo foo() {
?????????? return new Foo();
}
}
3.可以使用init-method和destory-method
public class Foo {
????? public void init() {
?????????? //初始化邏輯
}
}
?
public class Bar {
????? public void cleanup() {
?????????? //銷毀邏輯
}
}
?
@Configuration
public class AppConfig {
????? @Bean(initMethod="init")
????? public Foo foo() {
????? return new Foo();
}
@Bean(destoryMethod="cleanup")
public Bar bar() {
????? return new Bar();
}
}
?
4-6 Spring Bean裝配之基于Java的容器注解說明——@ImportResource和@Value(進(jìn)行資源文件讀取)
1.使用xml來進(jìn)行資源文件的讀取
<beans>
????? <context:annotation-config/>
//使用property-placeholder并指定location,來加載properties文件
????? <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>
?
????? <bean class="com.acme.AppConfig"/>
?
????? <bean class-"org.springframework.jdbc.datasource.DriverManagerDataSource">
?????????? property name="url" value="${jdbc.url}" />
??????? <property name="username" value="${jdbc.username}" />
??????? <property name="password" value="${jdbc.password}" />
????? </bean>
</beans>
2.使用注解進(jìn)行資源文件的讀取
@Configuration
@ImportResource("classpath:/com/acme/properties-config.xml")?? //導(dǎo)入資源文件
public class AppConfig {
????? @Value("${jdbc.url}")
????? private String url;
?
????? @Value("${jdbc.username}")
????? private String username;
?
@Value("${jdbc.password}")
????? private String password;
?
????? @Bean
????? public DataSource dataSource() {????? //創(chuàng)建bean并把成員變量賦給它
?????????? return new DriverManagerDataSource(url, username, password);
}
}
注意:在jdbc.properties中,要用jdbc.username,因?yàn)閡sername是當(dāng)前數(shù)據(jù)庫(kù)的用戶的用戶名,而jdbc.username是配置文件中的用戶名
?
4-7 Spring Bean裝配之基于Java的容器注解說明——@Bean和@Scope
1.@Bean默認(rèn)是單例的,使用@Scope可以改變,如:
@Configuration
public class MyConfiguration {
????? @Bean
????? @Scope("prototype")
????? public Encryptor encryptor() {
?????????? //…
}
}
或
@Bean
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public UserPerferences userPreferences() {
????? return new UserPreferences;
}
?
4-8 Spring Bean裝配之基于Java的容器注解說明——基于泛型的自動(dòng)裝配
1.使用
@Configuration
public class MyConfiguration {
????? @Bean
????? public StringStore stringStore() {
?????????? return new StringStore();
}
@Bean
????? public IntegerStore integerStore() {
?????????? return new IntegerStore();
}
}
(1)方式1
@Autowired
private Store<String> s1;
@Autowired
private Store<Integer> s2;
(2)方式2
@Autowired
private List<Store<Integer>> s;
2.@Autowired的拓展內(nèi)容——自定義qualifier注解
(1)CustomAtuowireConfigurer是BeanFactoryPostProcessor的子類,通過它可以注冊(cè)自己的qualifier注解類型(即使沒有通過Spring的@Qualifier注解)
<bean id="customAutowireConfigurer"
?????????? class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
????? <property name="customQualifierTypes">???? //用來放類型
?????????? <set>?? //這是set,可以放多個(gè)類型
???????????????? <value>example.CustomQualifier</value>
?????????? </set>
????? </property>
</bean>
(2)該AutowireCandidateResolver決定自動(dòng)裝配的候選者:
1°每個(gè)bean定義的autowire-candidate值
2°或任何<bean/>中的default-autowire-candidates
3°或@Qualifier注解及使用CustomAutowireConfigurer的自定義類型
?
4-9 Spring Bean裝配之Spring對(duì)JSR支持的說明
JSR:Java規(guī)范提案(任何人都可以提交“規(guī)范提案”,然后經(jīng)過委員會(huì)審核,隨著技術(shù)的發(fā)展,會(huì)圍繞其中某些規(guī)范做出對(duì)應(yīng)的實(shí)現(xiàn))
1.@Resource
(1)Spring支持使用JSR-250@Resource注解的變量或setter方法,這是一種在Java EE 5和6的通用模式,Spring管理的對(duì)象也支持這種模式
(2)@Resource有一個(gè)name屬性,并且默認(rèn)Spring解釋該值作為被注入bean的名稱
public class SimpleMovieListener {
????? private MovieFinder movieFinder;
?????
????? @Resource(name="myMovieFinder")
????? public void setMovieFinder(MovieFinder movieFinder) {
?????????? this.movieFinder = movieFinder;
}
}
(3)如果沒有顯示地指定@Resource的name,默認(rèn)的名稱是從屬性名或者setter方法得出
public class SimpleMovieListener {
????? private MovieFinder movieFinder;
?????
????? @Resource
????? public void setMovieFinder(MovieFinder movieFinder) {
?????????? this.movieFinder = movieFinder;
}
}
(4)注解提供的名字被解析為一個(gè)bean的名稱,這是由ApplicationContext中的CommonAnnotationBeanPostProcessor發(fā)現(xiàn)并處理的
2.@PostConstruct和@PreDestory
(1)CommonAnnotationBeanPostProcessor不僅能識(shí)別JSR-250中的聲明周期注解@Resource,在Spring2.5也引入支持了初始化回調(diào)和銷毀回調(diào)(回調(diào)即執(zhí)行一個(gè)方法前/后先執(zhí)行回調(diào)方法),前提是CommonAnnotationBeanPostProcessor是在Spring的ApplicationContext中注冊(cè)的,如:
public class CachingMoiveListener {
????? @PostConstruct
????? public void populatemovieCache() {
?????????? //…
}
?
@PreDestory
public void clearMovieCache() {
????? //…
}
}
3.JSR330的標(biāo)準(zhǔn)注解
(1)從Spring3.0開始支持JSR330標(biāo)準(zhǔn)注解(依賴注入注解),其掃描方式與Spring注解一致
(2)使用JSR330需要依賴javax.inject包
(3)使用Maven引入方式
<dependency>
????? <groupId>javax.inject</groupId>
????? <artifactId>javax.inject</artifactId>
????? <version>1</version>
</dependency>
4.@Inject
(1)@Inject等效于@Autowired,可以使用于類、屬性、方法、構(gòu)造器
import javax.inject.Inject;
?
public class SimpleMovieListener {
????? private MovieFinder movieFinder;
?????
????? @Inject
????? public void setMovieFinder(MovieFinder movieFinder) {
?????????? this.movieFinder = movieFinder;
}
}
5.@Named
(1)如果在一個(gè)IoC容器中有多個(gè)同類型的bean,如果想使用特定名稱進(jìn)行依賴注入,使用@Named
(2)@Named與@Component是等效的
(3)使用方式
1°
import javax.inject.Inject;
import javax.inject.Named;
?
public class SimpleMovieListener {
????? private MovieFinder movieFinder;
?????
????? @Inject
????? public void setMovieFinder(@Named("main") MovieFinder movieFinder) {
?????????? this.movieFinder = movieFinder;
}
}
2°
@Named("movieListener")
public class SimpleMovieListener {
????? private MovieFinder movieFinder;
?????
????? @Inject
????? public void setMovieFinder(MovieFinder movieFinder) {
?????????? this.movieFinder = movieFinder;
}
}
查看全部 -
@Autowired新用法
不能使用@Autowired的情況
查看全部 -
@Required
@Autowired
查看全部 -
Bean相關(guān)注解
元注解(自定義注解)
查看全部 -
Resources
查看全部 -
Bean的自動(dòng)裝配
查看全部 -
Bean的聲明周期
查看全部 -
spring Bean配置
查看全部 -
Spring注入方式
setter注入
構(gòu)造器注入
查看全部 -
IOC及Bean容器
查看全部 -
什么是框架?
框架的特點(diǎn)
為什么使用框架?
查看全部 -
spring適用范圍
查看全部 -
Spring內(nèi)容簡(jiǎn)概
查看全部 -
配置切入點(diǎn)Pointcut(找到某個(gè)功能模塊的具體方法)
execution用于匹配某個(gè)功能模塊的具體方法。
以下SpringAOP和Spring支持的AspectJ都支持。
execution(public * *(..)):執(zhí)行所有的public方法時(shí),進(jìn)行切入(執(zhí)行相應(yīng)切面的相應(yīng)功能)。
execution(* set*(..)):執(zhí)行所有的set方法時(shí),進(jìn)行切入。
execution(* com.xyz.service.AccountService.*(..)):執(zhí)行com.xyz.service.AccountService類下的所有方法(public/protected/private方法)時(shí),進(jìn)行切入。
execution(*?com.xyz.service..(..)):切入點(diǎn)為com.xyz.service包下的所有方法
execution(*?com.xyz.service...(..)):切入點(diǎn)為com.xyz.service包及其子包下的所有方法
以下為SpringAOP自己支持的。
查看全部 -
基于Schema-based配置的AOP實(shí)現(xiàn)
Spring所有的切面和通知器都必須放在<aop:config>內(nèi)(可以配置多個(gè)<aop:config>元素),每一個(gè)<aop:config>可以包含aspect,pointcout,advisor元素(它們必須按照這個(gè)順序進(jìn)行聲明)。
<aop:config>的配置大量使用了Spring的自動(dòng)代理機(jī)制。
該配置的含義:一個(gè)類作為切面來聲明,切面Id是myAspect,也就是說程序執(zhí)行某個(gè)功能模塊時(shí),通過pointcut和Joinpoint執(zhí)行該切面的功能。
案例:兩個(gè)類,一個(gè)類作為切面類,另一個(gè)作為業(yè)務(wù)類。(注意:<beans>中添加約束,xmlns:aop="http://www.springframework.org/schema/aop
)
代碼:
<?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:context="http://www.springframework.org/schema/context"
? ? ? ? xmlns:aop="http://www.springframework.org/schema/aop"
? ? xsi:schemaLocation="http://www.springframework.org/schema/beans
? ? ? ? http://www.springframework.org/schema/beans/spring-beans.xsd
? ? ? ? http://www.springframework.org/schema/context
? ? ? ? http://www.springframework.org/schema/context/spring-context.xsd ?
? ? ? ? http://www.springframework.org/schema/aop
? ? ? ? http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
? ? ? ? <bean id="aspectImooc" class="aspect.AspectImooc"></bean>
? ? ? ? <bean id="ServiceImooc" class="aspect.ServiceImooc"></bean>
? ? ? ? <aop:config>
? ? ? ? <aop:aspect id="aspectImoocAop" ref="aspectImooc"></aop:aspect>
? ? ? ? </aop:config>
查看全部
舉報(bào)