版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
Spring輕量、企業(yè)、對象容器、框架Spring
ProjectsSpringSpring
3.2.3的變化:Changes
in
version
3.2.3(2013-05-17)
-------------------------------------*
compatibility
with
OpenJDK
8for
1.5/1.6/1.7
compiled
Spring
Framework
3.2.x
applications
(SPR-9639)*
compatibility
with
OSGI-style
use
of
generics
in
source
code
that
got
compiled
to
1.4
byte
code
(SPR-10559)*consistent
detection
of
Order
annotation
in
superclasses
and
interfaces
(SPR-10514)*
fixed
regression
with
type
detection
for
child
bean
definitions
(SPR-10374)
*
fixed
configuration
classoverriding
in
terms
ofsuperclasses
(SPR-10546)*
minimized
ASM
usage
during
configuration
class
processing
(SPR-10292)*
added
public
"getName()"
accessor
to
MethodReference
(SPR-10422)
*
fixed
ReflectiveMethodResolver
toavoid
potential
UnsupportedOperationException
on
sort
(SPR-10392)
*
JdbcTemplate
defensively
uses
JDBC
3.0
getParameterType
call
for
Oracle
driver
compatibility
(SPR-10385)*
introduced
public
ArgumentPreparedStatementSetter
and
ArgumentTypePreparedStatementSetter
classes(SPR-10375)
*
fixed
BeanPropertyRowMapper
to
only
prefix
actual
upper-case
letters
with
underscores(SPR-10547)
*
HibernateJpaDialect
supports
Hibernate
4.2
as
a
JPA
provider
now
(SPR-10395)*
fixed
Jaxb2Marshaller's
partial
unmarshalling
feature
to
consistently
apply
to
all
sources
(SPR-10282)*
ContentNegotiationManager
properly
handles
HttpMessageConverter
checking
for
Accept
header
"*/*"(SPR-10513)*
SimpleMap
ExceptionResolver
prefers
longer
map
expression
in
case
of
same
exception
depth(SPR-9639)
*
ServletContextResourcePatternResolver
supports
Tomcat-style
"foo#bar.war"
deployment
unit
names(SPR-10471)*
fixed
potential
deadlock
with
DeferredResult
timeout
handling
on
Tomcat
(SPR-10485)*
fixedregression
with
ResourceHttpMessageConverteraccidentally
notclosing
underlying
files
(SPR-10460)*
fixed
regression
with
JSP
form
tag
prepending
the
context/servlet
path
(broke
use
for
Portlets;
SPR-10382)*
added
"jsonPrefix"
property
to
Map
Jackson(2)JsonView,allowing
for
a
custom
prefix
(SPR-10567)
*
changed
Map
Jackson(2)JsonView's
"writeContent"
template
method
to
include
"jsonPrefix"
String(SPR-10567)Spring簡介:輕量—從大小與開銷兩方面而言Spring都是輕量的。完整的Spring框架可以在一個(gè)大小只有1MB多的JAR文件里發(fā)布。并且Spring所需的處理開銷也是微不足道的。非侵入
——在應(yīng)用中,一般不需要
springjar包里的類??刂品崔D(zhuǎn)——Spring通過一種稱作控制反轉(zhuǎn)(IoC)的技術(shù)促進(jìn)了松耦合。當(dāng)應(yīng)用了IoC,某一接口的具體實(shí)現(xiàn)類的選擇控制權(quán)從調(diào)用類中移除,轉(zhuǎn)交給第裁決。面向切面(AOP)——Spring提供了面向切面編程的豐富支持,允許通過分離應(yīng)用的業(yè)務(wù)邏輯與系統(tǒng)級服務(wù)(例如審計(jì)(auditing)和事務(wù)()管理)進(jìn)行內(nèi)聚性的開發(fā)。應(yīng)用對象只實(shí)現(xiàn)它們應(yīng)該做的——完成業(yè)務(wù)邏輯——僅此而已。它們并不負(fù)責(zé)其它的系統(tǒng)級關(guān)注點(diǎn),例如日志或事務(wù)支持。Spring簡介:Spring即是一個(gè)容器又是一個(gè)框架。容器——Spring包含并管理應(yīng)用對象的配置和生命周期,在這個(gè)意義上它是一種容器,你可以配置你的每個(gè)bean如何被創(chuàng)建——基于一個(gè)可配置原型(prototype),你的bean可以創(chuàng)建一個(gè)單獨(dú)的實(shí)例或者每次需要時(shí)都生成一個(gè)新的實(shí)例——以及它們是如何相互關(guān)聯(lián)的??蚣堋猄pring提供了很多基礎(chǔ)的與業(yè)務(wù)邏輯無關(guān)的功能,比如:事務(wù)管理、持久化框架集成等等,使用Spring框架,開發(fā)可以專注于業(yè)務(wù)邏輯開發(fā),這個(gè)意義上講它是一個(gè)框架。為何要使用Spring?至少在我看來,在項(xiàng)目中引入spring立即可以帶來下面的好處降低組件之間的耦合度,實(shí)現(xiàn)
各層之間的解耦。使用??梢允褂萌萜魈峁┑谋姸喾?wù),如:事務(wù)管理服務(wù)、消息服務(wù)等等。當(dāng)容器管理事務(wù)時(shí),開發(fā)
就不再需要手工控制事務(wù).也不需處理復(fù)雜的事務(wù)容器提供單例模式支持,開發(fā)
不再需要自己編寫實(shí)現(xiàn)代碼。容器提供了AOP技術(shù),利用它很容易實(shí)現(xiàn)如權(quán)限
、運(yùn)行期
等功能。容器提供的眾多輔作類,使用這些類能夠加快應(yīng)用的開發(fā),如:JdbcTemplate、HibernateTemplate。Spring對于主流的應(yīng)用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,這樣更便于應(yīng)用的開發(fā)。Controller/Action/ServletServiceDAO傳統(tǒng)代碼的問題:嚴(yán)重依賴于實(shí)現(xiàn)而不是接口。如:public
classOneAction(){private
IOneDao
dao=new
OneDaoJdbc();//嚴(yán)重依賴}非常難以擴(kuò)展,必須修改原代碼。數(shù)據(jù)庫事務(wù)的控制與 的代碼交織在一塊,難以
?;蚴菙?shù)據(jù)庫事務(wù)的代碼粒度不夠細(xì)。不能明確標(biāo)明何種異常應(yīng)該回滾事務(wù)。如在這前的OSIV模式中,即使不是SQLException異常也會(huì)回滾事務(wù)。這就不夠細(xì)粒度。雖然在catch中可以根據(jù)捕獲的異?;貪L事務(wù)。Spring簡介:Spring是一個(gè)開源框架,是為了解決企業(yè)應(yīng)用開發(fā)的復(fù)雜性而創(chuàng)建的。Spring在 開發(fā)中所占的位置是承上啟下。目的:解決企業(yè)應(yīng)用開發(fā)的復(fù)雜性。功能:使用基本的JavaBean代替EJB(企業(yè)級JavaBean),并提供了應(yīng)用功能。范圍:任何Java應(yīng)用。的企業(yè)簡單來說,Spring是一個(gè)輕量級的控制反轉(zhuǎn)(IoC-InversionofControll)和面向切面(AOP-Aspect(j)
Oriented
Programming)的容器框架。StrutsSpringMVC服務(wù)層Dao層管理struts2的ActionHibernate管理hib的SessionIoC也叫DI-是指在運(yùn)行時(shí),由外部容器決定對象之間的依賴關(guān)系:AOP:Aspect(j)
Oriented
Programming–是OOP的補(bǔ)充和加強(qiáng)。Spring的模塊:-以下紅框部分是所關(guān)心的內(nèi)容:Spring的包結(jié)構(gòu):Spring3的包結(jié)構(gòu)。Jdk1.5以上。支持根據(jù)BeanID獲取Bean實(shí)例,支持泛型。支持根據(jù)類名-接口名獲取實(shí)例。支持表達(dá)式語言。#{…}支持新的線程池。直接支持任務(wù)調(diào)度。支持RESTfull。Spring3.x提供的Jar包說明:spring-context.jar:提供IoC高級功能,JNDI、EJB的支持等spring-aop.jar:Spring的AOP框架spring-dao.jar:提供了對數(shù)據(jù)庫的
抽象,提供了對JDBC和數(shù)據(jù)庫事務(wù)的支持spring-orm.jar:提供了對Hibernate,JDO,
iBATIS和OJB的支持spring-web.jar:提供了對web的支持spring-webmvc.jar:Spring自己的Web框架spring-mock.jar:提供了通過Mock方式進(jìn)
試的包org.springframework.beans所有應(yīng)用都要用到的,它包含
配置文件、創(chuàng)建和管理bean,以及進(jìn)行Inversion
of
Control
/Dependency
Injection(IoC/DI)操作相關(guān)的所有類工具類,Spring其它組件要都要使用
org.springframework.core包含Spring框架基本的到這個(gè)包里的類,是其它組件的基本org.springframework.asm
Spring獨(dú)立的asm程序org.springframework.expression
Spring表達(dá)式語言org.springframework.context.support
Spring提供在基礎(chǔ)IoC功能上的擴(kuò)展服務(wù),此外還提供、緩存以許多企業(yè)級服務(wù)的支持,如郵件服務(wù)、任務(wù)調(diào)度、JNDI定位、EJB集成、及各種視圖層框架的封裝等commons-logging
Spring日志功能Spring作為容器如何管理你的類:BeanFactory工廠BeanFactory.xml,Bean配置文件應(yīng)用程序?qū)嵗@取Bean實(shí)例返回Bean實(shí)例Spring提供了兩個(gè)類來管理系統(tǒng)中的類,調(diào)用這兩個(gè)類的某些方法即可以獲取到被容器管理的類。這兩個(gè)類是:1、BeanFactory2、ApplicationContextApplicationContext是BeanFactory的子接口。兩個(gè)類的初始化過程必須要配置文件。被Spring管理的不僅是JavaBean,
任意的類,
稱它們?yōu)镾pringBean.Spring:搭建Spring3的開發(fā)環(huán)境:以下是在Java環(huán)境下開發(fā)Spring使用的最少包:Beans
:
裝載beans的包。Context:應(yīng)用上下文。Core:
包。Logging:apache日志包。Expression:表達(dá)式。-必須使用應(yīng)用上下文才可以加載表達(dá)式,即ApplicationContext對象。Spring的配置文件:<beans><import
resource=“otherBeans.xml”/><bean
id=“someId”
name=“alias1,alias2”…></beans>Id:必須唯一。Name:即這個(gè)id的別名。且可以通過逗號分開。Import導(dǎo)入其他的配置文件。Spring:-
QuickStart:Spring的兩個(gè)重要容器類:BeanFactory
VS
ApplicationContext.BeanFactory通常稱為Bean容器。ApplicationContext通常稱為應(yīng)用上下文。它的功能要多于BeanFactory,如它可以加載外部的資源文件、可以自動(dòng)進(jìn)行AOP切面、可以識別自動(dòng) 的的類、可以識別用于
Bean創(chuàng)建的類等。-以下是使用ApplicationContext的示例:已經(jīng)不
使用方法:BeanFactory
bf
=
new
XmlBeanFactory(new
ClassPathResource("beans01.xml"));p
=
( )
bf.getBean("
");System.err.println("p
is:"+p);用應(yīng)用上下文實(shí)現(xiàn)的代碼:
:ApplicationContext
ac
=new
ClassPathXmlApplicationContext("beans01.xml");p
=
ac.getBean("
",
.class);通過BeanFactoryxml文件獲取Bean://
DefaultListableBeanFactoryBeanFactory
bf
=
new
DefaultListableBeanFactory();//
加載配置文件的類XmlBeanDefinitionReader
xdr
=
newXmlBeanDefinitionReader((DefaultListableBeanFactory)bf);//加載配置文件xdr.loadBeanDefinitions(new
ClassPathResource("beans01.xml"));//從BeanFacotry中獲取BeanObject
obj
=
bf.getBean("
");getBean(Class,T)getBean(Class)getBean(StringName)獲取到的將是同一個(gè)對象。Spring默認(rèn)以單例的方式管理所有Bean。理解IoC和DI:IoC:(InversionofControl,控制反轉(zhuǎn))控制反轉(zhuǎn)就是應(yīng)用程序本身不負(fù)責(zé)依賴對象的創(chuàng)建及,依賴對象的創(chuàng)建及是由外部容器負(fù)責(zé)。這樣控制權(quán)就由應(yīng)用程序本身轉(zhuǎn)移到了外部容器,控制權(quán)的轉(zhuǎn)移就是所謂的反轉(zhuǎn)。依賴注入(Dependency
Injection):就是在運(yùn)行期,由外部容器動(dòng)態(tài)的將依賴對象注入到組件中?;蚴窃谶\(yùn)行期,由外部容器決定具體執(zhí)行的類。理解IoC:ServiceBean
{//手工注入方式:public
classprivateDaoDaoBean();Dao
=
new){);public
void
save(Dao.save(}}DaoBean是在應(yīng)用
創(chuàng)建及的。如果需要擴(kuò)展或是修改,就必須要修改應(yīng)用程序本身的源代碼,這不符合OC原則。OC原則是指:OpenClose原則,即開閉原則。是指對修改關(guān)閉,對擴(kuò)展開放。見:<Java與模式>第四章。理解IOC:象編IoC不是一種技術(shù),只是一種思想,一個(gè)重要的面程的法則,它能指導(dǎo)
如何設(shè)計(jì)出松耦合、更優(yōu)良的程序。IoC很好的體現(xiàn)了面
象設(shè)計(jì)法則之一——好萊塢法則:“別找,找你”;即由IoC容器幫對象找相應(yīng)的依賴對象并注入,而不是由對象主動(dòng)去找。理解依賴注入(Dependency
Injection)把依賴對象交給外部容器負(fù)責(zé)創(chuàng)建,那么ServiceBean
類可以改成如當(dāng)下:public
class ServiceBean
{private
Dao Dao
;//通過構(gòu)造器參數(shù),讓容器把創(chuàng)建好的依賴對象注入進(jìn)
ServiceBean,當(dāng)然也可以使用setter方法進(jìn)行注入。ServiceBean(
DaoDao=
Dao;publicthis.}){);public
void
save(Dao.save(}}所謂依賴注入就是指:在運(yùn)行期,由外部容器動(dòng)態(tài)地將依賴對象注入到組件中。Dao){所謂依賴注入就是指:在運(yùn)行期,由外部容器動(dòng)態(tài)地將依賴對象注入到組件中。IOC
VS
DIIoC和DI由什么關(guān)系呢?其實(shí)它們是同一個(gè)概念的不同角度描述,由于控制反轉(zhuǎn)概念比較含糊(可能只是理解為容器控制對象這一個(gè)層面,很難讓人想到
對象關(guān)系),所以2004年大師級人物Martin
Fowler又給出了一個(gè)新的名字:“依賴注入”,相對IoC
而言,“依賴注入”明確描述了“被注入對象依賴IoC容器配置依賴對象”??刂品崔D(zhuǎn)-讓你類依賴接口而不是實(shí)際類,在運(yùn)行期間,由外部容器決定具體要執(zhí)行的類:配置你的Spring
Bean:搭建Spring的Java項(xiàng)目環(huán)境。由Spring容器管理所有Java類.Bean的范圍.Bean.構(gòu)造器注入和setter注入。裝配Bean,注入List,Map,Set,Array,注入其他Bean.自動(dòng)裝配??刂艬ean的創(chuàng)建和銷毀。Spring容器:Spring提供了兩種容器的實(shí)現(xiàn):
(前面已經(jīng)
)1、Bean工廠,由BeanFactory定義。是最簡單的容器。2、應(yīng)用上下文,由ApplicationContext定義,建立在Bean工廠之上,提供了系統(tǒng)構(gòu)架服務(wù),如從屬性文件中文本信息,向有關(guān)的事件器發(fā)布事件等。同時(shí)ApplicationContext是BeanFactory的子類。兩個(gè)容器都可以調(diào)用Bean的私有/公有構(gòu)造方法實(shí)例化一個(gè)類。它們兩個(gè)的區(qū)別:BeanFactory只有當(dāng)需要獲取一個(gè)Bean時(shí)才會(huì)去創(chuàng)建這個(gè)Bean的實(shí)例。ApplicationContext在啟動(dòng)時(shí)一次初始化所有Bean的實(shí)例、可以自動(dòng)識別 自動(dòng) 類、可以識別自動(dòng)加載Bean等,可以識別表達(dá)式#{…}BeanFactory的實(shí)現(xiàn)類-DefaultListableBeanFactory:DefaultListableBeanFactory是BeanFactory的子類。之前的XmlBeanFactory已經(jīng)不再建議使用:接收:Resource類的實(shí)現(xiàn):比較常用的資源定義為:
ClassPathResourceFileSystemResource—
從classpath中-從文件系統(tǒng)中ServletContextResource
-
必須要在web環(huán)境下使用BeanFactory
bf
=
new
DefaultListableBeanFactory();XmlBeanDefinitionReader
xdr
=newXmlBeanDefinitionReader((DefaultListableBeanFactory)bf);xdr.loadBeanDefinitions(new
ClassPathResource("beans01.xml"));ApplicationContext:DefaultListableBeanFactory對于簡單應(yīng)用來說,已經(jīng)非常好用。但為了獲取Spring框架強(qiáng)大的功能,你需要使用Spring的高級容器--應(yīng)用上下文。ApplicationContext的實(shí)現(xiàn)類為:ClassPathXmlApplicationContextFileSystemXmlApplicationContextXmlWebApplicationContext–需要Spring-web包的支持。工具類:WebApplicationContextUtils用于在Web環(huán)境下獲取容器。在web包中。ApplicationContext
ac
=new
ClassPathXmlApplicationContext("beans01.xml");Bean的裝配:通過構(gòu)造器注入。constrator-args通過setter方法注入。property
name=“xx”value|ref=xxx給Bean注入集合。list,map,給Bean注入其他Bean.,ref自動(dòng)裝配。通過構(gòu)造器注入:(注入值類型和類型)通過屬性注入:
(注入值類型和類型均可)"><bean
id="p4"
class="cn.beans1.<property
name="addr"><ref
bean="addr"/></property></bean><bean
id="addr"
class="cn.beans1.Address"><property
name="addr"
value="中國"/><property
name=" "value="12399"></property></bean>注入集合:注入null值:Bean的自動(dòng)裝配:自動(dòng)裝配是指Spring根據(jù)指定的自動(dòng)模式查找相關(guān)屬性并自動(dòng)裝配。Spring提供四種Bean的自動(dòng)裝配類型:byName-試圖在容器中查找與屬性名稱相同的Bean的id,如果沒有找到,則此屬性裝配不成功。byType-試圖在容器中查詢與屬性類型相同的Bean,如果沒有找到,則此屬性裝配不成功。如果找多個(gè)類型相符的Bean則會(huì)拋出
UnsatisfiedDependencyException異常。Constructor-查找與自動(dòng)裝配的Bean的構(gòu)造參數(shù)一致的一個(gè)或多個(gè)
Bean。如果存在不確定的Bean或是構(gòu)造,將會(huì)拋出一個(gè)異常。先會(huì)根據(jù)byName找,再根據(jù)byType找。Autodetect
-首先使用constructor來裝配,然后再嘗試用byType來裝配。注意,到了spring3.0中,此項(xiàng)已經(jīng)不再支持。byName自動(dòng)裝配:開發(fā)步驟:開發(fā)Address類及接口IAddress。開發(fā) 類并
Iaddress(接口)成員變量。在配置文件中通過byName自動(dòng)裝配。說明:如果沒有找到合適的名稱匹配,則屬性配置不成功,將返回null值。(不會(huì)拋出異常)byType自動(dòng)裝配:說明:以下例當(dāng)中,如果出現(xiàn)兩個(gè)相同類型的屬性則會(huì)在裝配時(shí)拋出異常。以下代碼將會(huì)拋出一個(gè)異常。因?yàn)橥瑫r(shí)存在兩個(gè)類型相同的Bean。Constructor-構(gòu)造器自動(dòng)裝配:第一步:
一個(gè)
類,并
兩個(gè)屬性。且不必提供getter/setter方法。第二步:
一個(gè)構(gòu)造方法,接收這兩個(gè)參數(shù)。第三步:配置如下。第四步:注意:構(gòu)造自動(dòng)裝配默認(rèn)使用
byType,所以當(dāng)有兩個(gè)相同類型的bean時(shí)將會(huì)拋出一個(gè)異常構(gòu)造器自己裝配細(xì)節(jié):是根據(jù)參數(shù)名還是根據(jù)成員變量名注入
Constructor自動(dòng)裝配,會(huì)先根據(jù)參數(shù)名
(注意是參數(shù)名,而不是成員變
量名)
先裝配,即byName,但這個(gè)這byName再確切的說應(yīng)該是byParameterName(這是我給它取名稱),而后會(huì)再根據(jù)byType進(jìn)行裝配,應(yīng)該叫做byParameterType。由于存在同名的參數(shù),則選擇one3何時(shí)使用自動(dòng)裝配:盡管自動(dòng)裝配給 帶來了很多方便,但同時(shí)也會(huì)帶來很多問題。如:按byType裝配,不能在容器中多次 一個(gè)Bean.目前自動(dòng)裝配最大的缺點(diǎn)是缺乏透明。由于自動(dòng)裝配隱藏了很多細(xì)節(jié),所以一般情況下,
不建議使用自動(dòng)裝配??刂艬ean的創(chuàng)建:1、Bean的范圍。3、利用工廠方法創(chuàng)建Bean.3、初始化和銷毀Bean.Bean的范圍:默認(rèn)情況下,所有Spring的Bean都是單一的。即單例。Bean的屬性scope屬性決定生成bean的方式:Singleton–
單例,默認(rèn)值
。Prototype
–每一次請求創(chuàng)建一個(gè)新的實(shí)例。Request–在web容器中,每一個(gè)request創(chuàng)建一個(gè)。Session–在web容器中,第一個(gè)會(huì)話創(chuàng)建一個(gè)實(shí)例。Global–session–Http會(huì)話,在portlet上才會(huì)有效。請考慮以下問題:問題1:如果一個(gè)Bean是原型模式,被注入的類是單例模式它們在容器中創(chuàng)建的次數(shù)。<bean
id="service"
class="cn.leaf.service.OneServiceImpl"scope="prototype"><property
name="dao"
ref="dao"></property></bean><bean
id="dao"
class="cn.leaf.dao.OneDaoJdbc"
scope="singleton"/>問題
2、如果將上面的情況反過來,它們在容器中創(chuàng)建的次數(shù)是多少?利用工廠方法來創(chuàng)建Bean:在某些情況下,如果你希望通過工廠方法來獲取Bean的實(shí)例。則可以提供一個(gè)factory-method方法。在創(chuàng)建之前,你可以在工廠方法中實(shí)現(xiàn)一些其他的細(xì)節(jié)。一般情況下,工廠方法返回當(dāng)前類的實(shí)例或是子類的實(shí)例。初始化和銷毀Bean:在bean元素中,定義init-method和destory-method屬性,可設(shè)置初始化方法和銷毀方法。需要注意的是:如果scope屬性為prototype則不受spring緩存的控制,
destory方法也將不會(huì)執(zhí)行。所以,如果希望由spring去調(diào)用銷毀方法,則不能使用
prototype類型的范圍。調(diào)用銷毀方法:如果需要Spring顯示的去調(diào)用銷毀方法,則必須銷毀整個(gè)Spring容器,即關(guān)閉或是銷毀BeanFactory或ApplicationContext。上面兩個(gè)接口中沒有定義關(guān)閉方法,必須使用它們的子類才可以關(guān)閉容器。容器的關(guān)閉,一般情況下不應(yīng)由程序代碼管理,應(yīng)該交給第
容器,如tomcat.也可以使用BeanFactory:高級Bean裝配:父子Bean。使用Spring的特殊Bean.外部的資源文件。父BeanBean:創(chuàng)建一個(gè)類來擴(kuò)展另一個(gè)類,是面 像的基礎(chǔ)之一。在Spring中, 的兩個(gè)Bean即使在實(shí)際類上沒有繼承關(guān)系,也是可以實(shí)現(xiàn)繼承的。Spring的Bean為 提供了兩個(gè)屬性可以實(shí)現(xiàn)繼承。Parent
–用于指明繼承的Bean,類似于extends關(guān)鍵字。?—
true|false.
- 一個(gè)Bean為抽象Bean,使用了關(guān)鍵字的類,不會(huì)被Spring容器實(shí)例化。父子Bean示例:1、 首先 了一個(gè)抽象類。
2、并在配置文件中使用了此類,和使用了關(guān)鍵字。父子Bean示例2-讓你不可思議:父子Bean需要注意的問題:在父Bean中定義的屬性必須要在子Bean中出現(xiàn)。如果子Bean中沒有定義相關(guān)屬性,將會(huì)導(dǎo)致容器初始化失敗。使用Spring的特殊Bean:
-非常關(guān)鍵Spring容器在多大數(shù)情況下,會(huì) 的對待所有Bean.但有些Bean有特殊的任務(wù),通過實(shí)現(xiàn)Spring的某些接口,可以將某些Bean當(dāng)成Spring容器的一部分。利用這些特殊的Bean
可以:對bean進(jìn)行后處理,介入Bean的創(chuàng)建。從外部資源文件加載信息。讓Bean了解容器。1、后處理Bean-介入Bean的創(chuàng)建:后處理Bean,即介入所有Bean的創(chuàng)建過程。接口BeanPostProcesser接口,為 提供了兩個(gè)機(jī)會(huì),可以在Bean創(chuàng)建和裝配之后修改Bean。BeanPostProcesser包含以下兩個(gè)方法:分別為:初始化之前,初始化之后。后處理Bean-BeanPostProcesser開發(fā)步驟:書寫一個(gè)單獨(dú)的類,實(shí)現(xiàn)BeanPostProcessor接口。在Bean創(chuàng)建時(shí)可以動(dòng)態(tài)修改Bean的行為,甚至它:配置你的后處理Bean:如果程序運(yùn)行于Bean工廠之內(nèi),即,你使用BeanFactory來初始化容器,則必須使用addBeanPostProcesser方法 ,如下:DefaultListableBeanFactory
bf
=
new
DefaultListableBeanFactory();XmlBeanDefinitionReader
xdr
=new
XmlBeanDefinitionReader((DefaultListableBeanFactory)bf);xdr.loadBeanDefinitions(new
ClassPathResource("beans01.xml"));后處理beanbf.addBeanPostProcessor(new
MyBeanPost());//Objectp2
=bf.getBean("two");System.err.println(p2);配置你的后處理Bean:然而常見的方法是使用上下文,即ApplicationContext來初始化容器,此時(shí)只要將后處理Bean配置到你的XML中,Spring容器在加載時(shí)即會(huì)此類,從而自動(dòng)去管理它:<!--
后處理Bean--><bean
class="cn.beans1.MyBeanPost"/><bean
id="two"
class="cn.beans1.Two"></bean>配置屬性的外在化:-經(jīng)常用于數(shù)據(jù)連接PropertyPlaceholderConfigurer類用于加載外部的資源文件。外部資源文件的另 式:-Spring
致力于讓配置更加簡化,但這意味著名空間:由于PropertyPlaceholderConfigurer字符過多,Spring給出來另一種部資源文件的方式,即使用context命名空間:命名空間:外"xmlns:context="schemaLocation:<context:property-placeholder
location="perties,perties"/>示例:使用外部的資源文件連接數(shù)據(jù)庫的示例引入外部的資源文件。需要添加jdbc包。配置簡單數(shù)據(jù)源。添加配置文件:name=Jack.mysql.jdbc.Driverurl=jdbc:mysql:///oracle?characterEncoding=UTF-8nm=rootpwd=1234外部資源文件:<context:property-placeholder
location="perties,perties"/>在bean文件中
:<bean
id="ds"
class="org.springframework.jdbc.datasource.SimpleDriverDataSource"><property
name="driverClass"
value="${driver}"/><propertyname="url"
value="${url}"/><property
name="username"
value="${nm}"></property><property
name="password"value="${pwd}"></property></bean>讓Bean了解容器:運(yùn)行在Spring中的Bean,就像是《》中的人類,無知便是福。Spring的Bean不知道自己,也不需要知道自己運(yùn)行在Spring的容器中。這通常是好事,因?yàn)橐坏┳孊ean了解容器,那它就與Spring耦合了。從而可能無法在容器之外生存。但在某些情況下,Bean需要了解自己在Spring中的名稱,了解自己運(yùn)行的環(huán)境。通過實(shí)現(xiàn)BeanNameAware,BeanFactoryAware,ApplicationContextAware接口,可以讓Bean了解它的名稱、BeanFactory、ApplicationContext。BeanNameAware通過實(shí)現(xiàn)接口BeanNameAware的方法setBeanName可以獲知自己的名稱。ApplicationContextAware:在某些情況下,Bean有時(shí)也需要程序的上下文。第二部分:AOP
–面向切面的編程:面向切面編程基礎(chǔ)AOP。通知。切點(diǎn)。從POJO切面創(chuàng)建AOP。從自動(dòng)
Bean創(chuàng)建AOP。AOP:Aspect(j)
Oriented
Programming–是OOP的補(bǔ)充和加強(qiáng)。AOP簡介:在程序中,散布于程序中多個(gè)地點(diǎn)的函數(shù)稱為“交叉事務(wù)”。將這些交叉事務(wù)與業(yè)務(wù)邏輯分離開正是面向切面編程的作用所在。描述切面的術(shù)語有:通知、切入點(diǎn)。通知都是Advice的子類,有些位于第 框架aopalliance.jar包中。切入點(diǎn)都是Pointer的子類。位于Spring的aop包中。以下是簡單的切面的說明:切面:都是Advisor的子類,位于spring的aop包中。即:org.springframework.aop-3.xx.jar同時(shí)需要cglib的支持。AOP-Advisor切面通知-是指什么時(shí)間執(zhí)行-Advice切入點(diǎn)-是指在什么地方執(zhí)行
-Pointcut在Spring當(dāng)中,通過將通知和切入點(diǎn)進(jìn)行關(guān)聯(lián)完整的定義一個(gè)切面切入被切入類的條件:1、必須要先定義好通知。2、必須要定義好切入點(diǎn)。3、必須已經(jīng)存在被切入類的實(shí)例。4、必須要將通知+切入點(diǎn)整
切面。5、被切入類必須是經(jīng)過 的類。要Spring中,使用CGLIB動(dòng)態(tài) 一個(gè)類,而使用CGLIB動(dòng)態(tài)一個(gè)類接口不是必須的。(有別于JDK的動(dòng)態(tài)
)。在Spring的包中,有兩個(gè)負(fù)責(zé)動(dòng)態(tài)ProxyFactoryProxyFactoryBean通過上面兩個(gè)類,獲取到的類為CGLIB的動(dòng)態(tài) 類。通知:通知:Advice類以及它的子類,并沒有存在于Spring的包中,所以,要想使用
Advice類,還要引入以下包:Aopallinace.jar你也可以將通知理解成 :以下是一個(gè)arround通知的類層將結(jié)構(gòu):(需要說明的是:在aopallinace.jar中,只定義了周圍通知,前通知,返回后通知,都是在spring的aop包中定義的,
但它們的最高父類,仍然是Advice。同時(shí)需要logging.jar和cglib.jar的支持。)通知分類:通知( )分類:Advice拋出后-after-throwingorg.springframework.aop.ThrowsAdvice前通知-beforeorg.springframework.aop.MethodBeforeAdvice后通知-after-returnorg.springframework.aop.AfterReturningAdvice周圍通知-around–注意,此類并沒有包含在Spring包中,而是在aopalliance.jar文件中,此文件需要單獨(dú)引入。erceptor.MethodInterceptor以下是MethodInterceptor為例演示如何實(shí)現(xiàn)方法
的AOP在Spring當(dāng)中,通過將通知和切入點(diǎn)進(jìn)行關(guān)聯(lián)完整的定義一個(gè)切面切點(diǎn)所有切點(diǎn)都是Pointcut(切點(diǎn))的子類-由Spring定義,在aop包中。經(jīng)常使用的子類如下:JdkRegexpMethodPointcutJDK正則表達(dá)式切點(diǎn)。必須在Spring的配置文件中配置。匹配需要被切入的方法。定義時(shí)使用正則表達(dá)式。以下將以此類為示例進(jìn)行演示。NameMat
ethodPointcut在Spring的配置文件中配置,只關(guān)注方法,也可以使用正則表達(dá)式。DynamicMethodMatcherPointcut動(dòng)態(tài)方法匹配切點(diǎn),可以配置,但必須要實(shí)現(xiàn)它的子類。JdkRegexpMethodPointcut正則表達(dá)式配置說明:此類的setPattern方法和setPatterns方法接收正則表達(dá)式類型的方法切入點(diǎn),示例如上。正則表達(dá)式說明:.(點(diǎn))匹配任意多個(gè)非\n字符。*(星)是指匹配的次數(shù)為0~N次。實(shí)現(xiàn)簡單AOP的步驟如下:第一步:準(zhǔn)備一個(gè)被 的類。第二步:書寫一個(gè)通知類。實(shí)現(xiàn)MethodInterceptor即可。第三步:書寫一個(gè)測試類,用于以下工作:1:類中重新獲取被被 類的
Bean。
-
ProxyFactoryBean2:
切點(diǎn)。-JdkRegexpMethodPointer3:將通知與切點(diǎn)整 為一個(gè)完整的AOP。-
DefaultPointcutAdvisor4:給
類 這個(gè)AOP。-
bean.addAdvisor(…)5:從6:強(qiáng)轉(zhuǎn)后執(zhí)行已經(jīng)被的類。-bean.getObject();的類的方法。需要導(dǎo)入以下包:第一步、第二步:第三步:測試類完整代碼示例:@Testpublic
void
aop2(){Two
two
=
new
Two();ProxyFactory
pf
=
new
ProxyFactory(two);//
通知Advice
advice
=
new
MethodInterceptor()
{public
Object
invoke(MethodInvocation
inv)
throws
Throwable{System.err.println("
o....");return
ceed();}};//
切點(diǎn)JdkRegexpMethodPointcut
cut
=
new
JdkRegexpMethodPointcut();cut.setPattern(".*Two.*");//
切面
–切面就是將通知和切點(diǎn)整合的過程Advisor
advisor
=
new
DefaultPointcutAdvisor(cut,advice);//給
添加切面pf.addAdvisor(advisor);//獲取
對象Two
tt=(Two)pf.getProxy();tt.say();//調(diào)用}通過配置文件完成方法:(在沒有自說明:通過配置文件完成切入功能,必須使用ProxyFactoryBean動(dòng) 的情況下),且必須指定 屬性的interceptorNames屬性。幾個(gè)重要的配置項(xiàng)目說明:1:配置通知。2:配置切入點(diǎn)。3:配置對像
。以下是調(diào)用代碼,配置代碼見下一面。使用BeanFactory或是使用Application:ProxyFactoryBean
VS
ProxyFactory說明ProxyFactoryBean適用于在Java類中于在XML中配置。它的幾個(gè)方法:setTaget
–
用于設(shè)置被 的類.或在XML中配置,但經(jīng)常用addAdvisor–用于在Java類中添加AOP.setInterceptorNames-用于在XML配置文件中設(shè)置getObject()
-
用于從 對像中返回被 的對像。ProxyFactory適用于在Java類中測試,不適合在XML中配置。它的幾個(gè)方法如下:setTaget
–
用于設(shè)置被 的類.addAdvisor–用于在Java類中添加AOP.getProxy
-類似于ProxyFactoryBean的getObject.的AOP。ProxyFactory
vs
ForxyFactoryBean:getObject獲取對象:getProxy獲取對象并于AOP的再說明:所有切點(diǎn)都是Pointcut的子類。其他子類如:DynamicMethodMatcherPointcutJdkRegexpMethodPointcutNameMat
ethodPointcut在Spring當(dāng)中,通過將通知和切入點(diǎn)進(jìn)行關(guān)聯(lián)完整的定義一個(gè)切面DynamicMethodMatcherPointcut-動(dòng)態(tài)切入點(diǎn):此類簡單了解:動(dòng)態(tài)切入點(diǎn),通過繼承DynamicMethodMatcherPointcut類加以實(shí)現(xiàn)?;蚴峭ㄟ^實(shí)現(xiàn)此類的子類可以在Spring中進(jìn)行配置,以實(shí)現(xiàn)動(dòng)態(tài)功能。以下是開發(fā)步驟:第一步:書寫一個(gè)需要被切入的類。第二步:書寫動(dòng)態(tài)切入點(diǎn)的子類即DynamicMethodMatcherPointcut的子類。第三步:書寫一個(gè)方法
器,即通知,繼承MethodInterceptor類。第四步:編寫測試類。加以調(diào)用。第一步、書寫一個(gè)需要被的類:第 步:編個(gè)方法切入點(diǎn):第三步:書寫一個(gè)通知:第四步:測試代碼:又:NameMatethodPointcut:-通過配置文件實(shí)現(xiàn):此類通過在配置文件中配置名稱進(jìn)行切入方法。聯(lián)合切入點(diǎn)與通知者:(一種快速的方式整合通知和切入點(diǎn))上面的配置中,有一種比較簡單的配置。即使用RegexpMethodPointcutAdvisor直接可以定義通知和切入點(diǎn)。RegexpMethodPointcutAdvisor的說明:通過定義此類,完成成兩個(gè)Bean的工作。(但通知還是必須要有的)Aspectj里面定義的切點(diǎn)才是一種真正的切點(diǎn)表達(dá)式語言。如果在定義Spring切點(diǎn)時(shí)想使用Aspectj樣式的表達(dá)式,就使用AspectJExpressionPointcut類。需要aspectj.jar文件,和aspectj-weaver.jar[必須]文件。此類通過execution表達(dá)式語言指定需要 的類的方法。如:execution(*
cn..*.*(..))
–
對所有cn下的類,返回任意值接收任意參數(shù)的方法
。也可以使用組合:execution(int
cn..*.*(..))
or
execution(String
cn..*.*(..))定義Aspectj的切點(diǎn):-真正的切點(diǎn)語言添加aspectj的jar包:在Java代碼中使用aspectj切面:@Testpublic
void
aop2(){Two
two
=
new
Two();ProxyFactory
pf=
newProxyFactory(two);Advice
advice
=
new
MethodInterceptor()
{public
Object
invoke(MethodInvocation
inv)
throws
Throwable
{System.err.println("
");returnceed();}};AspectJExpressionPointcut
cut
=
new
AspectJExpressionPointcut();cut.setExpression("execution(*
cn..*.*(..))");Advisor
advisor
=
new
DefaultPointcutAdvisor(cut,advice);pf.addAdvisor(advisor);Two
tt
=
(Two)
pf.getProxy();tt.say();}在Java代碼中使用aspectj切面:-直接使用切面與切點(diǎn)類@Testpublic
void
aop2(){Two
two
=
new
Two();ProxyFactory
pf
=
new
ProxyFactory(two);Advice
advice
=
new
MethodInterceptor()
{public
Object
invoke(MethodInvocation
inv)
throws
Throwable{System.err.println("
....");return
ceed();}};AspectJExpressionPointcutAdvisor
aop
=new
AspectJExpressionPointcutAdvisor();aop.setExpression("execution(int
cn..*.*(..))
or
execution(*
cn..*.*())");aop.setAdvice(advice);pf.addAdvisor(aop);Two
tt
=
(Two)
pf.getProxy();tt.say();}定義Aspectj的切點(diǎn)–在配置文件中定義aspectj切點(diǎn):<bean
id="two"
class="cn.beans1.Two"><property
name="name"
value="FFFFFFFFFFF"></property></bean><!--
通知
--><bean
id="advice"
class="cn.aop.MyAdvice"/><!--
切點(diǎn)
--><bean
id="cut"
class="org.springframework.aop.aspectj.AspectJExpressionPointcut"><property
name="expression"
value="execution(*
cn..*.*(..))"/></bean><!--
切面--><bean
id="advisor"
class="org.springframework.aop.support.DefaultPointcutAdvisor"><property
name="advice"
ref="advice"/><property
name="pointcut"
ref="cut"></property></bean><!--
類和注入切面
--><bean
id="twoProxy"
class="org.springframework.aop.framework.ProxyFactoryBean"><property
name=" "
ref="two"></property><property
name="interceptorNames"><list><value>advisor</value></list></property></bean>定義Aspectj切點(diǎn):也可以使用AspectJExpressionPointcutAdvisor類直接將通知與切入點(diǎn) 在一個(gè)類中:使用ProxyFactoryBean:作為被通知者的Bean,它必須是被 的。,并且將獲取的是它Spring的ProxyFactoryBean是個(gè)工廠Bean,用于生成一個(gè)一個(gè)或多個(gè)切面(通知+切面)添加Bean,獲取此對象所
的實(shí)例,而不是它本身。以下是一個(gè)典型的示例:自動(dòng)—非常重要問題:為每一個(gè)被 的Bean創(chuàng)建一個(gè)ProxyFactoryBean讓代碼變得冗長。如果只需要Bean創(chuàng)建一次,就讓Spring為每個(gè)具有與通知和切入點(diǎn)相匹配的,那豈不是更好。為此Spring提供了兩種實(shí)現(xiàn):基于Spring上下文中 者Bean的基本自動(dòng)
:通知者的切點(diǎn)表達(dá)式,用于決定哪個(gè)Bean的哪個(gè)方法要被
。基于@AspectJ注解驅(qū)動(dòng)切面的自動(dòng)
。注意:在使用了自動(dòng)ApplicationContext以后,必須使用應(yīng)用上下文對象即Bean才可以實(shí)現(xiàn)N:為Spring切面創(chuàng)建自動(dòng)
-1:Spring提供了BeanPostProcesser的一個(gè)方便實(shí)現(xiàn):DefaultAdvisorAutoProxyCreator,它會(huì)自動(dòng)檢查通知者的切點(diǎn)是否匹配Bean的方法,并且使用通知的 來替換這個(gè)Bean的定義。配置DefaultAdvisorAutoProxyCreator類,不需要提供ID,因?yàn)椴粫?huì)
利用它創(chuàng)建它,Spring容器會(huì)識別它為一個(gè)BeanPostProcesser,并。配置DefaultAdvisorAutoProxyCreator后處理類,實(shí)現(xiàn)自動(dòng)的
:<bean
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/><!--正常配置自己的Bean即可
--><bean
id="two"
class="cn.beans1.Two"><property
name="name"
value="FFFFFFFFFFF"></property></bean><!--
通知
--><bean
id="advice"
class="cn.aop.MyAdvice"/><!--
切點(diǎn)
--><bean
id="cut"
class="org.springframework.aop.aspectj.AspectJExpressionPointcut"><property
name="expression"
value="execution(*cn..*.*(..))"/></bean><!--
切面
--><bean
id="advisor"
class="org.springframework.aop.support.DefaultPointcutAdvisor"><property
name="advice"
ref="advice"/><property
name="pointcut"
ref="cut"></property></bean>//以下是不用再ProxyFactoryBean對two類進(jìn)行測試代碼:ApplicationContext
ac
=new
ClassPathXmlApplicationContext("beans01.xml");Two
two
=
ac.getBean("two",Two.class);two.say();使用@AspectJ注解的自動(dòng)
:AspectJ5的一個(gè)主要功能是可以將一個(gè)POJO類注解成切面。這通常被稱為@Aspect以下注解定義一個(gè)切面:請注意類中的注解。需要
aspectj.jar包。在@Before,@After中可以接收org.aspectj.lang.JoinPoint參數(shù)。在@Around中必須接收
ProceedingJoinPoint參數(shù),并調(diào)用proceed()方法。在@Around中可以返回一個(gè)
Object值,從而可以修改被調(diào)用方法的返回值。注解說明:@Pointcut切點(diǎn)定義,此切點(diǎn)定義了準(zhǔn)備要切入 的方法。@Pointcut注解定義在一個(gè)方法上,此方法實(shí)際上應(yīng)該是一個(gè)空的。方法本身只是一個(gè)標(biāo)記,讓@Pointcut注解能夠?qū)⒆约焊郊悠渖?。在定義了注解后,為了讓Spring自動(dòng) 這些注解類,必須要在spring中定義一個(gè)AnnotationAwareAspectJAutoProxyCreator的Bean。此Bean不需要ID,它會(huì)完成與DefaultAdvisorAutoProxyCreator同樣的工作。右邊是包含返回值和接收參數(shù)的切面:配置文件:<bean//
可以識別注解的后處理Beanclass="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"
/>//
添加了注解的切面@Aspect<bean
class="cn.aop.AOP"></bean>//正常 自己的Bean即可<bean
id="two"
class="cn.beans1.Two"><propertyname="name"
value=“So
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025-2030年中國中端酒店行業(yè)并購重組擴(kuò)張戰(zhàn)略制定與實(shí)施研究報(bào)告
- 2025-2030年中國家庭服務(wù)機(jī)器人行業(yè)商業(yè)模式創(chuàng)新戰(zhàn)略制定與實(shí)施研究報(bào)告
- 2025-2030年中國虛擬養(yǎng)老院行業(yè)營銷創(chuàng)新戰(zhàn)略制定與實(shí)施研究報(bào)告
- 2025-2030年中國新型健康服務(wù)行業(yè)營銷創(chuàng)新戰(zhàn)略制定與實(shí)施研究報(bào)告
- 2025-2030年中國礦山開發(fā)服務(wù)行業(yè)開拓第二增長曲線戰(zhàn)略制定與實(shí)施研究報(bào)告
- 建設(shè)社會(huì)主義文化強(qiáng)國論文
- 中國心理測試儀器行業(yè)市場深度分析及發(fā)展趨勢預(yù)測報(bào)告
- 一年級數(shù)學(xué)計(jì)算題專項(xiàng)練習(xí)匯編
- 大客車常用知識培訓(xùn)課件
- 年產(chǎn)40000噸環(huán)保新能源材料生產(chǎn)線項(xiàng)目可行性研究報(bào)告寫作模板-拿地申報(bào)
- 圍手術(shù)期血糖的管理
- 2024年度醫(yī)療器械監(jiān)督管理?xiàng)l例培訓(xùn)課件
- 項(xiàng)目七電子商務(wù)消費(fèi)者權(quán)益保護(hù)的法律法規(guī)
- 100以內(nèi)不進(jìn)位不退位加減法練習(xí)題
- 企業(yè)安全生產(chǎn)評估報(bào)告
- 水庫大壩深基坑開挖專項(xiàng)方案樣本
- 經(jīng)橈動(dòng)脈腦血管造影術(shù)前術(shù)后護(hù)理
- 品質(zhì)經(jīng)理工作總結(jié)
- 運(yùn)行設(shè)備巡回檢查制度模版
- 肯德基經(jīng)營策略分析報(bào)告總結(jié)
- 噴涂主管年后業(yè)務(wù)規(guī)劃暨工作計(jì)劃
評論
0/150
提交評論