spring基礎-iocdiaop p輕量、企業(yè)對象容器框架_第1頁
spring基礎-iocdiaop p輕量、企業(yè)對象容器框架_第2頁
spring基礎-iocdiaop p輕量、企業(yè)對象容器框架_第3頁
spring基礎-iocdiaop p輕量、企業(yè)對象容器框架_第4頁
spring基礎-iocdiaop p輕量、企業(yè)對象容器框架_第5頁
已閱讀5頁,還剩102頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

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框架可以在一個大小只有1MB多的JAR文件里發(fā)布。并且Spring所需的處理開銷也是微不足道的。非侵入

——在應用中,一般不需要

springjar包里的類??刂品崔D——Spring通過一種稱作控制反轉(IoC)的技術促進了松耦合。當應用了IoC,某一接口的具體實現(xiàn)類的選擇控制權從調(diào)用類中移除,轉交給第裁決。面向切面(AOP)——Spring提供了面向切面編程的豐富支持,允許通過分離應用的業(yè)務邏輯與系統(tǒng)級服務(例如審計(auditing)和事務()管理)進行內(nèi)聚性的開發(fā)。應用對象只實現(xiàn)它們應該做的——完成業(yè)務邏輯——僅此而已。它們并不負責其它的系統(tǒng)級關注點,例如日志或事務支持。Spring簡介:Spring即是一個容器又是一個框架。容器——Spring包含并管理應用對象的配置和生命周期,在這個意義上它是一種容器,你可以配置你的每個bean如何被創(chuàng)建——基于一個可配置原型(prototype),你的bean可以創(chuàng)建一個單獨的實例或者每次需要時都生成一個新的實例——以及它們是如何相互關聯(lián)的??蚣堋猄pring提供了很多基礎的與業(yè)務邏輯無關的功能,比如:事務管理、持久化框架集成等等,使用Spring框架,開發(fā)可以專注于業(yè)務邏輯開發(fā),這個意義上講它是一個框架。為何要使用Spring?至少在我看來,在項目中引入spring立即可以帶來下面的好處降低組件之間的耦合度,實現(xiàn)

各層之間的解耦。使用??梢允褂萌萜魈峁┑谋姸喾?,如:事務管理服務、消息服務等等。當容器管理事務時,開發(fā)

就不再需要手工控制事務.也不需處理復雜的事務容器提供單例模式支持,開發(fā)

不再需要自己編寫實現(xiàn)代碼。容器提供了AOP技術,利用它很容易實現(xiàn)如權限

、運行期

等功能。容器提供的眾多輔作類,使用這些類能夠加快應用的開發(fā),如:JdbcTemplate、HibernateTemplate。Spring對于主流的應用框架提供了集成支持,如:集成Hibernate、JPA、Struts等,這樣更便于應用的開發(fā)。Controller/Action/ServletServiceDAO傳統(tǒng)代碼的問題:嚴重依賴于實現(xiàn)而不是接口。如:public

classOneAction(){private

IOneDao

dao=new

OneDaoJdbc();//嚴重依賴}非常難以擴展,必須修改原代碼。數(shù)據(jù)庫事務的控制與 的代碼交織在一塊,難以

。或是數(shù)據(jù)庫事務的代碼粒度不夠細。不能明確標明何種異常應該回滾事務。如在這前的OSIV模式中,即使不是SQLException異常也會回滾事務。這就不夠細粒度。雖然在catch中可以根據(jù)捕獲的異?;貪L事務。Spring簡介:Spring是一個開源框架,是為了解決企業(yè)應用開發(fā)的復雜性而創(chuàng)建的。Spring在 開發(fā)中所占的位置是承上啟下。目的:解決企業(yè)應用開發(fā)的復雜性。功能:使用基本的JavaBean代替EJB(企業(yè)級JavaBean),并提供了應用功能。范圍:任何Java應用。的企業(yè)簡單來說,Spring是一個輕量級的控制反轉(IoC-InversionofControll)和面向切面(AOP-Aspect(j)

Oriented

Programming)的容器框架。StrutsSpringMVC服務層Dao層管理struts2的ActionHibernate管理hib的SessionIoC也叫DI-是指在運行時,由外部容器決定對象之間的依賴關系:AOP:Aspect(j)

Oriented

Programming–是OOP的補充和加強。Spring的模塊:-以下紅框部分是所關心的內(nèi)容:Spring的包結構:Spring3的包結構。Jdk1.5以上。支持根據(jù)BeanID獲取Bean實例,支持泛型。支持根據(jù)類名-接口名獲取實例。支持表達式語言。#{…}支持新的線程池。直接支持任務調(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ù)庫事務的支持spring-orm.jar:提供了對Hibernate,JDO,

iBATIS和OJB的支持spring-web.jar:提供了對web的支持spring-webmvc.jar:Spring自己的Web框架spring-mock.jar:提供了通過Mock方式進

試的包org.springframework.beans所有應用都要用到的,它包含

配置文件、創(chuàng)建和管理bean,以及進行Inversion

of

Control

/Dependency

Injection(IoC/DI)操作相關的所有類工具類,Spring其它組件要都要使用

org.springframework.core包含Spring框架基本的到這個包里的類,是其它組件的基本org.springframework.asm

Spring獨立的asm程序org.springframework.expression

Spring表達式語言org.springframework.context.support

Spring提供在基礎IoC功能上的擴展服務,此外還提供、緩存以許多企業(yè)級服務的支持,如郵件服務、任務調(diào)度、JNDI定位、EJB集成、及各種視圖層框架的封裝等commons-logging

Spring日志功能Spring作為容器如何管理你的類:BeanFactory工廠BeanFactory.xml,Bean配置文件應用程序?qū)嵗@取Bean實例返回Bean實例Spring提供了兩個類來管理系統(tǒng)中的類,調(diào)用這兩個類的某些方法即可以獲取到被容器管理的類。這兩個類是:1、BeanFactory2、ApplicationContextApplicationContext是BeanFactory的子接口。兩個類的初始化過程必須要配置文件。被Spring管理的不僅是JavaBean,

任意的類,

稱它們?yōu)镾pringBean.Spring:搭建Spring3的開發(fā)環(huán)境:以下是在Java環(huán)境下開發(fā)Spring使用的最少包:Beans

:

裝載beans的包。Context:應用上下文。Core:

包。Logging:apache日志包。Expression:表達式。-必須使用應用上下文才可以加載表達式,即ApplicationContext對象。Spring的配置文件:<beans><import

resource=“otherBeans.xml”/><bean

id=“someId”

name=“alias1,alias2”…></beans>Id:必須唯一。Name:即這個id的別名。且可以通過逗號分開。Import導入其他的配置文件。Spring:-

QuickStart:Spring的兩個重要容器類:BeanFactory

VS

ApplicationContext.BeanFactory通常稱為Bean容器。ApplicationContext通常稱為應用上下文。它的功能要多于BeanFactory,如它可以加載外部的資源文件、可以自動進行AOP切面、可以識別自動 的的類、可以識別用于

Bean創(chuàng)建的類等。-以下是使用ApplicationContext的示例:已經(jīng)不

使用方法:BeanFactory

bf

=

new

XmlBeanFactory(new

ClassPathResource("beans01.xml"));p

=

( )

bf.getBean("

");System.err.println("p

is:"+p);用應用上下文實現(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)獲取到的將是同一個對象。Spring默認以單例的方式管理所有Bean。理解IoC和DI:IoC:(InversionofControl,控制反轉)控制反轉就是應用程序本身不負責依賴對象的創(chuàng)建及,依賴對象的創(chuàng)建及是由外部容器負責。這樣控制權就由應用程序本身轉移到了外部容器,控制權的轉移就是所謂的反轉。依賴注入(Dependency

Injection):就是在運行期,由外部容器動態(tài)的將依賴對象注入到組件中?;蚴窃谶\行期,由外部容器決定具體執(zhí)行的類。理解IoC:ServiceBean

{//手工注入方式:public

classprivateDaoDaoBean();Dao

=

new){);public

void

save(Dao.save(}}DaoBean是在應用

創(chuàng)建及的。如果需要擴展或是修改,就必須要修改應用程序本身的源代碼,這不符合OC原則。OC原則是指:OpenClose原則,即開閉原則。是指對修改關閉,對擴展開放。見:<Java與模式>第四章。理解IOC:象編IoC不是一種技術,只是一種思想,一個重要的面程的法則,它能指導

如何設計出松耦合、更優(yōu)良的程序。IoC很好的體現(xiàn)了面

象設計法則之一——好萊塢法則:“別找,找你”;即由IoC容器幫對象找相應的依賴對象并注入,而不是由對象主動去找。理解依賴注入(Dependency

Injection)把依賴對象交給外部容器負責創(chuàng)建,那么ServiceBean

類可以改成如當下:public

class ServiceBean

{private

Dao Dao

;//通過構造器參數(shù),讓容器把創(chuàng)建好的依賴對象注入進

ServiceBean,當然也可以使用setter方法進行注入。ServiceBean(

DaoDao=

Dao;publicthis.}){);public

void

save(Dao.save(}}所謂依賴注入就是指:在運行期,由外部容器動態(tài)地將依賴對象注入到組件中。Dao){所謂依賴注入就是指:在運行期,由外部容器動態(tài)地將依賴對象注入到組件中。IOC

VS

DIIoC和DI由什么關系呢?其實它們是同一個概念的不同角度描述,由于控制反轉概念比較含糊(可能只是理解為容器控制對象這一個層面,很難讓人想到

對象關系),所以2004年大師級人物Martin

Fowler又給出了一個新的名字:“依賴注入”,相對IoC

而言,“依賴注入”明確描述了“被注入對象依賴IoC容器配置依賴對象”??刂品崔D-讓你類依賴接口而不是實際類,在運行期間,由外部容器決定具體要執(zhí)行的類:配置你的Spring

Bean:搭建Spring的Java項目環(huán)境。由Spring容器管理所有Java類.Bean的范圍.Bean.構造器注入和setter注入。裝配Bean,注入List,Map,Set,Array,注入其他Bean.自動裝配??刂艬ean的創(chuàng)建和銷毀。Spring容器:Spring提供了兩種容器的實現(xiàn):

(前面已經(jīng)

)1、Bean工廠,由BeanFactory定義。是最簡單的容器。2、應用上下文,由ApplicationContext定義,建立在Bean工廠之上,提供了系統(tǒng)構架服務,如從屬性文件中文本信息,向有關的事件器發(fā)布事件等。同時ApplicationContext是BeanFactory的子類。兩個容器都可以調(diào)用Bean的私有/公有構造方法實例化一個類。它們兩個的區(qū)別:BeanFactory只有當需要獲取一個Bean時才會去創(chuàng)建這個Bean的實例。ApplicationContext在啟動時一次初始化所有Bean的實例、可以自動識別 自動 類、可以識別自動加載Bean等,可以識別表達式#{…}BeanFactory的實現(xiàn)類-DefaultListableBeanFactory:DefaultListableBeanFactory是BeanFactory的子類。之前的XmlBeanFactory已經(jīng)不再建議使用:接收:Resource類的實現(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對于簡單應用來說,已經(jīng)非常好用。但為了獲取Spring框架強大的功能,你需要使用Spring的高級容器--應用上下文。ApplicationContext的實現(xiàn)類為:ClassPathXmlApplicationContextFileSystemXmlApplicationContextXmlWebApplicationContext–需要Spring-web包的支持。工具類:WebApplicationContextUtils用于在Web環(huán)境下獲取容器。在web包中。ApplicationContext

ac

=new

ClassPathXmlApplicationContext("beans01.xml");Bean的裝配:通過構造器注入。constrator-args通過setter方法注入。property

name=“xx”value|ref=xxx給Bean注入集合。list,map,給Bean注入其他Bean.,ref自動裝配。通過構造器注入:(注入值類型和類型)通過屬性注入:

(注入值類型和類型均可)"><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的自動裝配:自動裝配是指Spring根據(jù)指定的自動模式查找相關屬性并自動裝配。Spring提供四種Bean的自動裝配類型:byName-試圖在容器中查找與屬性名稱相同的Bean的id,如果沒有找到,則此屬性裝配不成功。byType-試圖在容器中查詢與屬性類型相同的Bean,如果沒有找到,則此屬性裝配不成功。如果找多個類型相符的Bean則會拋出

UnsatisfiedDependencyException異常。Constructor-查找與自動裝配的Bean的構造參數(shù)一致的一個或多個

Bean。如果存在不確定的Bean或是構造,將會拋出一個異常。先會根據(jù)byName找,再根據(jù)byType找。Autodetect

-首先使用constructor來裝配,然后再嘗試用byType來裝配。注意,到了spring3.0中,此項已經(jīng)不再支持。byName自動裝配:開發(fā)步驟:開發(fā)Address類及接口IAddress。開發(fā) 類并

Iaddress(接口)成員變量。在配置文件中通過byName自動裝配。說明:如果沒有找到合適的名稱匹配,則屬性配置不成功,將返回null值。(不會拋出異常)byType自動裝配:說明:以下例當中,如果出現(xiàn)兩個相同類型的屬性則會在裝配時拋出異常。以下代碼將會拋出一個異常。因為同時存在兩個類型相同的Bean。Constructor-構造器自動裝配:第一步:

一個

類,并

兩個屬性。且不必提供getter/setter方法。第二步:

一個構造方法,接收這兩個參數(shù)。第三步:配置如下。第四步:注意:構造自動裝配默認使用

byType,所以當有兩個相同類型的bean時將會拋出一個異常構造器自己裝配細節(jié):是根據(jù)參數(shù)名還是根據(jù)成員變量名注入

Constructor自動裝配,會先根據(jù)參數(shù)名

(注意是參數(shù)名,而不是成員變

量名)

先裝配,即byName,但這個這byName再確切的說應該是byParameterName(這是我給它取名稱),而后會再根據(jù)byType進行裝配,應該叫做byParameterType。由于存在同名的參數(shù),則選擇one3何時使用自動裝配:盡管自動裝配給 帶來了很多方便,但同時也會帶來很多問題。如:按byType裝配,不能在容器中多次 一個Bean.目前自動裝配最大的缺點是缺乏透明。由于自動裝配隱藏了很多細節(jié),所以一般情況下,

不建議使用自動裝配??刂艬ean的創(chuàng)建:1、Bean的范圍。3、利用工廠方法創(chuàng)建Bean.3、初始化和銷毀Bean.Bean的范圍:默認情況下,所有Spring的Bean都是單一的。即單例。Bean的屬性scope屬性決定生成bean的方式:Singleton–

單例,默認值

。Prototype

–每一次請求創(chuàng)建一個新的實例。Request–在web容器中,每一個request創(chuàng)建一個。Session–在web容器中,第一個會話創(chuàng)建一個實例。Global–session–Http會話,在portlet上才會有效。請考慮以下問題:問題1:如果一個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的實例。則可以提供一個factory-method方法。在創(chuàng)建之前,你可以在工廠方法中實現(xiàn)一些其他的細節(jié)。一般情況下,工廠方法返回當前類的實例或是子類的實例。初始化和銷毀Bean:在bean元素中,定義init-method和destory-method屬性,可設置初始化方法和銷毀方法。需要注意的是:如果scope屬性為prototype則不受spring緩存的控制,

destory方法也將不會執(zhí)行。所以,如果希望由spring去調(diào)用銷毀方法,則不能使用

prototype類型的范圍。調(diào)用銷毀方法:如果需要Spring顯示的去調(diào)用銷毀方法,則必須銷毀整個Spring容器,即關閉或是銷毀BeanFactory或ApplicationContext。上面兩個接口中沒有定義關閉方法,必須使用它們的子類才可以關閉容器。容器的關閉,一般情況下不應由程序代碼管理,應該交給第

容器,如tomcat.也可以使用BeanFactory:高級Bean裝配:父子Bean。使用Spring的特殊Bean.外部的資源文件。父BeanBean:創(chuàng)建一個類來擴展另一個類,是面 像的基礎之一。在Spring中, 的兩個Bean即使在實際類上沒有繼承關系,也是可以實現(xiàn)繼承的。Spring的Bean為 提供了兩個屬性可以實現(xiàn)繼承。Parent

–用于指明繼承的Bean,類似于extends關鍵字。?—

true|false.

- 一個Bean為抽象Bean,使用了關鍵字的類,不會被Spring容器實例化。父子Bean示例:1、 首先 了一個抽象類。

2、并在配置文件中使用了此類,和使用了關鍵字。父子Bean示例2-讓你不可思議:父子Bean需要注意的問題:在父Bean中定義的屬性必須要在子Bean中出現(xiàn)。如果子Bean中沒有定義相關屬性,將會導致容器初始化失敗。使用Spring的特殊Bean:

-非常關鍵Spring容器在多大數(shù)情況下,會 的對待所有Bean.但有些Bean有特殊的任務,通過實現(xiàn)Spring的某些接口,可以將某些Bean當成Spring容器的一部分。利用這些特殊的Bean

可以:對bean進行后處理,介入Bean的創(chuàng)建。從外部資源文件加載信息。讓Bean了解容器。1、后處理Bean-介入Bean的創(chuàng)建:后處理Bean,即介入所有Bean的創(chuàng)建過程。接口BeanPostProcesser接口,為 提供了兩個機會,可以在Bean創(chuàng)建和裝配之后修改Bean。BeanPostProcesser包含以下兩個方法:分別為:初始化之前,初始化之后。后處理Bean-BeanPostProcesser開發(fā)步驟:書寫一個單獨的類,實現(xiàn)BeanPostProcessor接口。在Bean創(chuàng)建時可以動態(tài)修改Bean的行為,甚至它:配置你的后處理Bean:如果程序運行于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來初始化容器,此時只要將后處理Bean配置到你的XML中,Spring容器在加載時即會此類,從而自動去管理它:<!--

后處理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了解容器:運行在Spring中的Bean,就像是《》中的人類,無知便是福。Spring的Bean不知道自己,也不需要知道自己運行在Spring的容器中。這通常是好事,因為一旦讓Bean了解容器,那它就與Spring耦合了。從而可能無法在容器之外生存。但在某些情況下,Bean需要了解自己在Spring中的名稱,了解自己運行的環(huán)境。通過實現(xiàn)BeanNameAware,BeanFactoryAware,ApplicationContextAware接口,可以讓Bean了解它的名稱、BeanFactory、ApplicationContext。BeanNameAware通過實現(xiàn)接口BeanNameAware的方法setBeanName可以獲知自己的名稱。ApplicationContextAware:在某些情況下,Bean有時也需要程序的上下文。第二部分:AOP

–面向切面的編程:面向切面編程基礎AOP。通知。切點。從POJO切面創(chuàng)建AOP。從自動

Bean創(chuàng)建AOP。AOP:Aspect(j)

Oriented

Programming–是OOP的補充和加強。AOP簡介:在程序中,散布于程序中多個地點的函數(shù)稱為“交叉事務”。將這些交叉事務與業(yè)務邏輯分離開正是面向切面編程的作用所在。描述切面的術語有:通知、切入點。通知都是Advice的子類,有些位于第 框架aopalliance.jar包中。切入點都是Pointer的子類。位于Spring的aop包中。以下是簡單的切面的說明:切面:都是Advisor的子類,位于spring的aop包中。即:org.springframework.aop-3.xx.jar同時需要cglib的支持。AOP-Advisor切面通知-是指什么時間執(zhí)行-Advice切入點-是指在什么地方執(zhí)行

-Pointcut在Spring當中,通過將通知和切入點進行關聯(lián)完整的定義一個切面切入被切入類的條件:1、必須要先定義好通知。2、必須要定義好切入點。3、必須已經(jīng)存在被切入類的實例。4、必須要將通知+切入點整

切面。5、被切入類必須是經(jīng)過 的類。要Spring中,使用CGLIB動態(tài) 一個類,而使用CGLIB動態(tài)一個類接口不是必須的。(有別于JDK的動態(tài)

)。在Spring的包中,有兩個負責動態(tài)ProxyFactoryProxyFactoryBean通過上面兩個類,獲取到的類為CGLIB的動態(tài) 類。通知:通知:Advice類以及它的子類,并沒有存在于Spring的包中,所以,要想使用

Advice類,還要引入以下包:Aopallinace.jar你也可以將通知理解成 :以下是一個arround通知的類層將結構:(需要說明的是:在aopallinace.jar中,只定義了周圍通知,前通知,返回后通知,都是在spring的aop包中定義的,

但它們的最高父類,仍然是Advice。同時需要logging.jar和cglib.jar的支持。)通知分類:通知( )分類:Advice拋出后-after-throwingorg.springframework.aop.ThrowsAdvice前通知-beforeorg.springframework.aop.MethodBeforeAdvice后通知-after-returnorg.springframework.aop.AfterReturningAdvice周圍通知-around–注意,此類并沒有包含在Spring包中,而是在aopalliance.jar文件中,此文件需要單獨引入。erceptor.MethodInterceptor以下是MethodInterceptor為例演示如何實現(xiàn)方法

的AOP在Spring當中,通過將通知和切入點進行關聯(lián)完整的定義一個切面切點所有切點都是Pointcut(切點)的子類-由Spring定義,在aop包中。經(jīng)常使用的子類如下:JdkRegexpMethodPointcutJDK正則表達式切點。必須在Spring的配置文件中配置。匹配需要被切入的方法。定義時使用正則表達式。以下將以此類為示例進行演示。NameMat

ethodPointcut在Spring的配置文件中配置,只關注方法,也可以使用正則表達式。DynamicMethodMatcherPointcut動態(tài)方法匹配切點,可以配置,但必須要實現(xiàn)它的子類。JdkRegexpMethodPointcut正則表達式配置說明:此類的setPattern方法和setPatterns方法接收正則表達式類型的方法切入點,示例如上。正則表達式說明:.(點)匹配任意多個非\n字符。*(星)是指匹配的次數(shù)為0~N次。實現(xiàn)簡單AOP的步驟如下:第一步:準備一個被 的類。第二步:書寫一個通知類。實現(xiàn)MethodInterceptor即可。第三步:書寫一個測試類,用于以下工作:1:類中重新獲取被被 類的

Bean。

ProxyFactoryBean2:

切點。-JdkRegexpMethodPointer3:將通知與切點整 為一個完整的AOP。-

DefaultPointcutAdvisor4:給

類 這個AOP。-

bean.addAdvisor(…)5:從6:強轉后執(zhí)行已經(jīng)被的類。-bean.getObject();的類的方法。需要導入以下包:第一步、第二步:第三步:測試類完整代碼示例:@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();}};//

切點JdkRegexpMethodPointcut

cut

=

new

JdkRegexpMethodPointcut();cut.setPattern(".*Two.*");//

切面

–切面就是將通知和切點整合的過程Advisor

advisor

=

new

DefaultPointcutAdvisor(cut,advice);//給

添加切面pf.addAdvisor(advisor);//獲取

對象Two

tt=(Two)pf.getProxy();tt.say();//調(diào)用}通過配置文件完成方法:(在沒有自說明:通過配置文件完成切入功能,必須使用ProxyFactoryBean動 的情況下),且必須指定 屬性的interceptorNames屬性。幾個重要的配置項目說明:1:配置通知。2:配置切入點。3:配置對像

。以下是調(diào)用代碼,配置代碼見下一面。使用BeanFactory或是使用Application:ProxyFactoryBean

VS

ProxyFactory說明ProxyFactoryBean適用于在Java類中于在XML中配置。它的幾個方法:setTaget

用于設置被 的類.或在XML中配置,但經(jīng)常用addAdvisor–用于在Java類中添加AOP.setInterceptorNames-用于在XML配置文件中設置getObject()

用于從 對像中返回被 的對像。ProxyFactory適用于在Java類中測試,不適合在XML中配置。它的幾個方法如下:setTaget

用于設置被 的類.addAdvisor–用于在Java類中添加AOP.getProxy

-類似于ProxyFactoryBean的getObject.的AOP。ProxyFactory

vs

ForxyFactoryBean:getObject獲取對象:getProxy獲取對象并于AOP的再說明:所有切點都是Pointcut的子類。其他子類如:DynamicMethodMatcherPointcutJdkRegexpMethodPointcutNameMat

ethodPointcut在Spring當中,通過將通知和切入點進行關聯(lián)完整的定義一個切面DynamicMethodMatcherPointcut-動態(tài)切入點:此類簡單了解:動態(tài)切入點,通過繼承DynamicMethodMatcherPointcut類加以實現(xiàn)?;蚴峭ㄟ^實現(xiàn)此類的子類可以在Spring中進行配置,以實現(xiàn)動態(tài)功能。以下是開發(fā)步驟:第一步:書寫一個需要被切入的類。第二步:書寫動態(tài)切入點的子類即DynamicMethodMatcherPointcut的子類。第三步:書寫一個方法

器,即通知,繼承MethodInterceptor類。第四步:編寫測試類。加以調(diào)用。第一步、書寫一個需要被的類:第 步:編個方法切入點:第三步:書寫一個通知:第四步:測試代碼:又:NameMatethodPointcut:-通過配置文件實現(xiàn):此類通過在配置文件中配置名稱進行切入方法。聯(lián)合切入點與通知者:(一種快速的方式整合通知和切入點)上面的配置中,有一種比較簡單的配置。即使用RegexpMethodPointcutAdvisor直接可以定義通知和切入點。RegexpMethodPointcutAdvisor的說明:通過定義此類,完成成兩個Bean的工作。(但通知還是必須要有的)Aspectj里面定義的切點才是一種真正的切點表達式語言。如果在定義Spring切點時想使用Aspectj樣式的表達式,就使用AspectJExpressionPointcut類。需要aspectj.jar文件,和aspectj-weaver.jar[必須]文件。此類通過execution表達式語言指定需要 的類的方法。如:execution(*

cn..*.*(..))

對所有cn下的類,返回任意值接收任意參數(shù)的方法

。也可以使用組合:execution(int

cn..*.*(..))

or

execution(String

cn..*.*(..))定義Aspectj的切點:-真正的切點語言添加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切面:-直接使用切面與切點類@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的切點–在配置文件中定義aspectj切點:<bean

id="two"

class="cn.beans1.Two"><property

name="name"

value="FFFFFFFFFFF"></property></bean><!--

通知

--><bean

id="advice"

class="cn.aop.MyAdvice"/><!--

切點

--><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切點:也可以使用AspectJExpressionPointcutAdvisor類直接將通知與切入點 在一個類中:使用ProxyFactoryBean:作為被通知者的Bean,它必須是被 的。,并且將獲取的是它Spring的ProxyFactoryBean是個工廠Bean,用于生成一個一個或多個切面(通知+切面)添加Bean,獲取此對象所

的實例,而不是它本身。以下是一個典型的示例:自動—非常重要問題:為每一個被 的Bean創(chuàng)建一個ProxyFactoryBean讓代碼變得冗長。如果只需要Bean創(chuàng)建一次,就讓Spring為每個具有與通知和切入點相匹配的,那豈不是更好。為此Spring提供了兩種實現(xiàn):基于Spring上下文中 者Bean的基本自動

:通知者的切點表達式,用于決定哪個Bean的哪個方法要被

?;贎AspectJ注解驅(qū)動切面的自動

。注意:在使用了自動ApplicationContext以后,必須使用應用上下文對象即Bean才可以實現(xiàn)N:為Spring切面創(chuàng)建自動

-1:Spring提供了BeanPostProcesser的一個方便實現(xiàn):DefaultAdvisorAutoProxyCreator,它會自動檢查通知者的切點是否匹配Bean的方法,并且使用通知的 來替換這個Bean的定義。配置DefaultAdvisorAutoProxyCreator類,不需要提供ID,因為不會

利用它創(chuàng)建它,Spring容器會識別它為一個BeanPostProcesser,并。配置DefaultAdvisorAutoProxyCreator后處理類,實現(xiàn)自動的

:<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"/><!--

切點

--><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類進行測試代碼:ApplicationContext

ac

=new

ClassPathXmlApplicationContext("beans01.xml");Two

two

=

ac.getBean("two",Two.class);two.say();使用@AspectJ注解的自動

:AspectJ5的一個主要功能是可以將一個POJO類注解成切面。這通常被稱為@Aspect以下注解定義一個切面:請注意類中的注解。需要

aspectj.jar包。在@Before,@After中可以接收org.aspectj.lang.JoinPoint參數(shù)。在@Around中必須接收

ProceedingJoinPoint參數(shù),并調(diào)用proceed()方法。在@Around中可以返回一個

Object值,從而可以修改被調(diào)用方法的返回值。注解說明:@Pointcut切點定義,此切點定義了準備要切入 的方法。@Pointcut注解定義在一個方法上,此方法實際上應該是一個空的。方法本身只是一個標記,讓@Pointcut注解能夠?qū)⒆约焊郊悠渖?。在定義了注解后,為了讓Spring自動 這些注解類,必須要在spring中定義一個AnnotationAwareAspectJAutoProxyCreator的Bean。此Bean不需要ID,它會完成與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)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論