Java EE輕量級框架應用實戰-SSM框架(Spring MVC+Spring+MyBatis)(第2版)課件 第7、8章 Spring Bean、Spring AOP_第1頁
Java EE輕量級框架應用實戰-SSM框架(Spring MVC+Spring+MyBatis)(第2版)課件 第7、8章 Spring Bean、Spring AOP_第2頁
Java EE輕量級框架應用實戰-SSM框架(Spring MVC+Spring+MyBatis)(第2版)課件 第7、8章 Spring Bean、Spring AOP_第3頁
Java EE輕量級框架應用實戰-SSM框架(Spring MVC+Spring+MyBatis)(第2版)課件 第7、8章 Spring Bean、Spring AOP_第4頁
Java EE輕量級框架應用實戰-SSM框架(Spring MVC+Spring+MyBatis)(第2版)課件 第7、8章 Spring Bean、Spring AOP_第5頁
已閱讀5頁,還剩93頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

Bean的配置Bean的實例化Bean配置方式Bean的作用域Bean的生命周期第7章

SpringBean2024/1/29學習目標/Target2了解Bean的常用屬性及其子元素掌握實例化Bean的3種方式

熟悉Bean的作用域和生命周期

了解常用作用域singleton和prototype

掌握Bean的3種裝配方式章節概述/Summary3第6章詳細講解了控制反轉和依賴注入,它們實現了組件的實例化不再由應用程序完成,轉而交由Spring容器完成,從而將組件之間的依賴關系進行了解耦。控制反轉和依賴注入都是通過Bean實現的,Bean是注冊到Spring容器中的Java類,任何一個Java類都可以是一個Bean。Bean由Spring進行管理,本章將針對Bean的管理進行詳細講解。目錄/CONTENTSBean的配置Bean的作用域Bean配置方式Bean的實例化4Bean的生命周期14325Bean的配置01第7章SpringBean什么是Spring中的Bean?Bean的配置6如果把Spring看做一個大型工廠,則Spring容器中的Bean就是該工廠的產品。要想使用這個工廠生產和管理Bean,就需要在配置文件中告訴它需要哪些Bean,以及需要使用何種方式將這些Bean裝配到一起。

小提示:Bean的本質就是Java中的類,而Spring中的Bean其實就是對實體類的引用,來生產Java類對象,從而實現生產和管理Bean。Bean的配置7Spring容器支持兩種格式的配置文件XML文件Properties文件

在實際開發中,最常使用的是XML文件格式的配置方式,這種配置方式是通過XML文件來注冊并管理Bean之間的依賴關系。Spring容器所支持的配置文件格式

Spring容器支持XML和Properties兩種格式的配置文件,在實際開發中,最常用的是XML格式的配置文件。XML是標準的數據傳輸和存儲格式,方便查看和操作數據。在Spring中,XML配置文件的根元素是<beans>,<beans>元素包含<bean>子元素,每個<bean>子元素可以定義一個Bean,通過<bean>元素將Bean注冊到Spring容器中。Bean的配置8

XML配置文件的根元素是<beans>,<beans>中包含了多個<bean>子元素,每一個<bean>子元素定義了一個Bean,并描述了該Bean如何被裝配到Spring容器中。關于<beans>元素的常用屬性如下表所示:屬性描述idid屬性是<bean>元素的唯一標識符,Spring容器對Bean的配置和管理通過id屬性完成,裝配Bean時也需要根據id值獲取對象。

name

name屬性可以為Bean指定多個名稱,每個名稱之間用逗號或分號隔開。

classclass屬性可以指定Bean的具體實現類,其屬性值為對象所屬類的全路徑。scopescope屬性用于設定Bean實例的作用范圍,其屬性值有:singleton(單例)、prototype(原型)、request、session和globalsession。<bean>元素的常用子元素9元素描述<constructor-arg>

使用<constructor-arg>元素可以為Bean的屬性指定值。

<property>

<property>元素的作用是調用Bean實例中的setter方法完成屬性賦值,從而完成依賴注入。

ref

ref是<property>、<constructor-arg>等元素的屬性,可用于指定Bean工廠中某個Bean實例的引用;也可用于指定Bean工廠中某個Bean實例的引用。value

value是<property>、<constructor-arg>等元素的屬性,用于直接指定一個常量值;也可以用于直接指定一個常量值。<list><list>元素是<property>等元素的子元素,用于指定Bean的屬性類型為List或數組。

<set><set>元素是<property>等元素的子元素,用于指定Bean的屬性類型為set。<map><map>元素是<property>等元素的子元素,用于指定Bean的屬性類型為Map。<entry>entry>元素是<map>元素的子元素,用于設定一個鍵值對。<entry>元素的key屬性指定字符串類型的鍵。Bean的配置10

在配置文件中,通常一個普通的Bean只需要定義id(或name)和class兩個屬性即可,定義Bean的方式如下所示:<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd">

<beanid="bean1"class="com.test.Bean1"/><beanname="bean2"class="com.test.Bean2"/></beans>

小提示:如果在Bean中未指定id和name,則Spring會將class值當作id使用。BeanFactory接口的常用方法BeanFactory接口11方法名稱描述getBean(Stringname)根據參數名稱獲取Bean

getBean(Stringname,Class<T>type)根據參數名稱、參數類型獲取Bean

<T>TgetBean(Class<T>requiredType)根據參數類型獲取Bean

ObjectgetBean(Stringname,Object...args)根據參數名稱獲取Bean

isTypeMatch(Stringname,ResolvableTypetype)判斷是否有與參數名稱、參數類型匹配的Bean

Class<?>getType(Stringname)根據參數名稱獲取類型String[]getAliases(Stringname)根據實例的名字獲取實例的別名數組booleancontainsBean(Stringname)根據Bean的名稱判斷Spring容器是否含有指定的Bean

BeanFactory接口實例的語法格式Spring提供了幾個BeanFactory接口的實現類,其中最常用的是XmlBeanFactory,它可以讀取XML文件并根據XML文件中的配置信息生成BeanFactory接口的實例,BeanFactory接口的實例用于管理Bean。XmlBeanFactory類讀取XML文件生成BeanFactory接口實例的具體語法格式如下。BeanFactory接口12BeanFactorybeanFactory=newXmlBeanFactory (newFileSystemResource(”D:/bean.xml”));ApplicationContext接口的特點

ApplicationContext接口建立在BeanFactory接口的基礎之上,它豐富了BeanFactory接口的特性,例如,添加了對國際化、資源訪問、事件傳播等方面的支持。

ApplicationContext接口可以為單例的Bean實行預初始化,并根據<property>元素執行setter方法,單例的Bean可以直接使用,提升了程序獲取Bean實例的性能。ApplicationContext接口13ApplicationContext接口的常用實現類ApplicationContext接口14類名稱描述ClassPathXmlApplicationContext

從類路徑加載配置文件,實例化ApplicationContext接口FileSystemXmlApplicationContext

從文件系統加載配置文件,實例化ApplicationContext接口AnnotationConfigApplicationContext

從注解中加載配置文件,實例化ApplicationContext接口WebApplicationContext

在Web應用中使用,從相對于Web根目錄的路徑中加載配置文件,實例化ApplicationContext接口ConfigurableWebApplicationContext擴展了WebApplicationContext類,它可以通過讀取XML配置文件的方式實例化WebApplicationContext類Bean的實例化02第7章SpringBeanBean的實例化有哪些方式?Bean的實例化16

在面向對象的程序中,想要使用某個對象,就需要先實例化這個對象。同樣,在Spring中,要想使用容器中的Bean,也需要實例化Bean。實例化Bean有三種方式,分別為構造器實例化、靜態工廠方式實例化和實例工廠方式實例化(其中最常用的是構造器實例化)。構造器實例化17創建Web項目,導入相關Jar包;創建名為Bean1的Java類;創建Spring配置文件beans1.xml,并配置Bean1實體類Bean;創建測試類,測試程序。<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-4.3.xsd"><beanid="bean1"class="com.test.instance.constructor.Bean1"/></beans>

構造器實例化是指Spring容器通過Bean對應的類中默認的構造函數來實例化Bean。接下來演示構造器實例化的使用:publicclassInstanceTest1{publicstaticvoidmain(String[]args){ StringxmlPath="com/test/instance/constructor/beans1.xml";ApplicationContextapplicationContext= newClassPathXmlApplicationContext(xmlPath); Bean1bean=(Bean1)applicationContext.getBean("bean1");System.out.println(bean);}}靜態工廠方式實例化18創建名為Bean2的Java類;創建一個Java工廠類,在類中使用靜態方法獲取Bean2實例;創建Spring配置文件beans2.xml,并配置工廠類Bean;創建測試類,測試程序。<beanid="bean2"class="com.test.instance.static_factory.MyBean2Factory" factory-method="createBean"/>

靜態工廠是實例化Bean的另一種方式。該方式要求自己創建一個靜態工廠的方法來創建Bean的實例。接下來演示靜態工廠實例化的使用:publicclassInstanceTest2{publicstaticvoidmain(String[]args){ StringxmlPath="com/test/instance/static_factory/beans2.xml"; ApplicationContextapplicationContext= newClassPathXmlApplicationContext(xmlPath); System.out.println(applicationContext.getBean("bean2"));}}publicclassMyBean2Factory{ publicstaticBean2createBean(){returnnewBean2();}}實例工廠方式實例化19創建名為Bean3的Java類;創建一個Java工廠類,在類中使用非靜態方法獲取Bean3實例;創建Spring配置文件beans3.xml,并配置工廠類Bean;創建測試類,測試程序。<beanid="myBean3Factory"class="com.test.instance.factory.MyBean3Factory"/><beanid="bean3"factory-bean="myBean3Factory"factory-method="createBean"/>

實例工廠是采用直接創建Bean實例的方式,在配置文件中,通過factory-bean屬性配置一個實例工廠,然后使用factory-method屬性確定使用工廠中的哪個方法。接下來演示實例工廠實例化的使用:publicclassInstanceTest3{publicstaticvoidmain(String[]args){ StringxmlPath="com/test/instance/factory/beans3.xml"; ApplicationContextapplicationContext= newClassPathXmlApplicationContext(xmlPath); System.out.println(applicationContext.getBean("bean3"));}}publicclassMyBean3Factory{publicBean3createBean(){returnnewBean3();}}使用不同方式實現Bean的實例化20需求說明修改第6章的案例,開發第一個Spring項目,輸出“Hello,Spring!”,具體要求如下。(1)編寫HelloSpring.java,輸出“Hello,Spring!”。(2)將Spring字符串通過Spring賦值到HelloSpring.java中。(3)分別使用構造器實例化Bean、靜態工廠實例化Bean和實例工廠實例化Bean。共性問題集中講解21常見問題及解決辦法代碼規范問題調試技巧共性問題集中講解Bean配置方式

——基于XML的配置03第7章SpringBean什么是Bean的裝配?Bean的裝配方式23

Bean的裝配可以理解為依賴關系注入,Bean的裝配方式即Bean依賴注入的方式。Spring容器支持多種形式的Bean的裝配方式,如基于XML的裝配、基于注解(Annotation)的裝配和自動裝配(其中最常用的是基于注解的裝配),本節將主要講解這三種裝配方式的使用。基于XML的裝配24基于XML的裝配(2種方式)構造注入(ConstructorInjection)設值注入(SetterInjection)必備以下條件必備以下條件Bean類必須有一個無參構造方法Bean類必須為屬性提供setter方法Bean類必須提供有參構造方法在配置文件中,使用<property>元素來為每個屬性注入值配置文件中,使用<constructor-arg>元素來為參數注入值

基于XML的裝配,使用方式如下:創建Java類,提供有參、無參構造以及屬性setter方法;創建Spring配置文件beans5.xml,使用2種方式配置Bean;創建測試類,測試程序。<beanid="user1"class="com.test.assemble.User"> <constructor-argindex="0"value="tom"/>...</bean><beanid="user2"class="com.test.assemble.User"> <propertyname=“username”value=“張三”/>...</bean>publicclassXmlBeanAssembleTest{publicstaticvoidmain(String[]args){ StringxmlPath="com/test/assemble/beans5.xml"; ApplicationContextapplicationContext= newClassPathXmlApplicationContext(xmlPath);System.out.println(applicationContext.getBean("user1"));System.out.println(applicationContext.getBean("user2"));}}publicUser(Stringusername,Integerpassword,List<String>list){ super(); this.username=username; this.password=password; this.list=list;}publicUser(){super();}......//省略屬性setter方法基于XML的裝配25使用構造方法注入實現為屬性賦值26需求說明(1)修改第6章的案例,輸出內容如下。張三說:“Spring的初衷是使JavaEE輕量級框架開發更加簡單。”李四說:“Spring的IoC,也稱DI,是OOP中的一種設計理念,用來降低代碼之間的耦合度。”(2)將說話人和說話內容都通過構造方法注入。共性問題集中講解27常見問題及解決辦法代碼規范問題調試技巧共性問題集中講解使用p命名空間實現屬性setter方法注入28從Spring2.0的配置文件開始采用schema形式,可以使用不同的命名空間管理不同類型的配置,使配置文件更具擴展性。例如,曾經使用AOP命名空間的元素可以實現置入切面的功能,在本章及之后章節內容的學習中讀者還會接觸更多其他命名空間的配置。此外,Spring基于schema形式的配置為許多領域的問題提供了簡化的配置方法,大大簡化了配置。<!--使用p命名空間注入屬性值--><beanid="user"class="cn.dsscm.pojo.User"p:username="張三"p:age="23"

p:email="zhangsan@163.com"/>使用p命名空間實現屬性setter方法注入29對于直接量(基本數據類型、string類型)的屬性語法p:屬性名="屬性值"對于引用Bean的屬性語法p:屬性名-ref="Bean的id"使用p命名空間實現直接量的注入30需求說明(1)修改本章上機練習2的實現代碼,對說話人和說話內容使用p命名空間通過屬性setter方法注入。(2)輸出內容如下。張三說:“Spring的初衷是使JavaEE輕量級框架開發更加簡單。”李四說:“Spring的IoC,也稱DI,是OOP中的一種設計理念,用來降低代碼之間的耦合度。”共性問題集中講解31常見問題及解決辦法代碼規范問題調試技巧共性問題集中講解注入不同數據類型32注入直接量(基本數據類型、string類型)引用其他Bean引用內部Bean注入集合類型屬性注入空字符串和nullBean配置方式

——基于注解的配置04第7章SpringBean基于Annotation的裝配34

基于XML的裝配可能會導致XML配置文件過于臃腫,給后續的維護和升級帶來一定的困難。為此,Spring提供了對Annotation(注解)技術的全面支持。注解描述@Component指定一個普通的Bean,可以作用在任何層次。@Controller指定一個控制器組件Bean,用于將控制層的類標識為Spring中的Bean,功能上等同于@Component。@Service指定一個業務邏輯組件Bean,用于將業務邏輯層的類標識為Spring中的Bean,功能上等同于@Component。@Repository指定一個數據訪問組件Bean,用于將數據訪問層的類標識為Spring中的Bean,功能上等同于@Component。@Scope指定Bean實例的作用域。@Value指定Bean實例的注入值。@Autowired指定要自動裝配的對象。@Resource指定要注入的對象。@Qualifier指定要自動裝配的對象名稱,通常與@Autowired聯合使用。@PostConstruct指定Bean實例完成初始化后調用的方法。@PreDestroy指定Bean實例銷毀前調用的方法。基于Annotation的裝配35基于Annotation裝配的使用方式如下:JDBC驅動器:由數據庫廠商創建,也稱為JDBC驅動程序。負責與特定的數據庫連接,以及處理通信細節。創建接口UserDao,并定義方法;創建接口實現類UserDaoImpl,用@Repository聲明類;創建接口UserService,并定義方法;創建接口實現類UserServiceImpl,用@Service聲明類,并使用@Resource注入UserDao屬性;創建控制器類,用@Controller聲明,并使用@Resource注入UserService屬性;創建Spring配置文件,配置Bean;創建測試類,測試程序。@Repository("userDao")publicclassUserDaoImplimplementsUserDao{publicvoidsave(){System.out.println("userdao...save...");}}publicclassAnnotationAssembleTest{publicstaticvoidmain(String[]args){StringxmlPath="com/test/annotation/beans6.xml"; ApplicationContextapplicationContext= newClassPathXmlApplicationContext(xmlPath); UserControlleruserController= (UserController)applicationContext.getBean("userController"); userController.save();}}<context:annotation-config/><beanid="userDao"class="com.test.annotation.UserDaoImpl"/><beanid="userService"class="com.test.annotation.UserServiceImpl"/><beanid="userController"class="com.test.annotation.UserController"/>@Service("userService")publicclassUserServiceImplimplementsUserService{ @Resource(name="userDao") privateUserDaouserDao; publicvoidsave(){ this.userDao.save(); }}@Controller("userController")publicclassUserController{ @Resource(name="userService") privateUserServiceuserService; publicvoidsave(){ this.userService.save(); }}

小提示:

除了可以像示例中通過<bean>元素來配置Bean外,還可以通過包掃描的形式來配置一個包下的所有Bean:<context:component-scanbase-package="com.test.annotation"/>Bean配置方式

——自動配置05第7章SpringBean自動裝配37

所謂自動裝配,就是將一個Bean自動的注入到到其他Bean的Property中。Spring的<bean>元素中包含一個autowire屬性,我們可以通過設置autowire的屬性值來自動裝配Bean。autowire屬性有5個值,其值及說明下表所示:屬性值描述default(默認值)由<bean>的上級元素<beans>的default-autowire屬性值確定。byName

根據<bean>元素id屬性的值自動裝配。

byType

根據<bean>元素的數據類型(Type)自動裝配,如果一個Bean的數據類型,兼容另一個Bean中的數據類型,則自動裝配。constructor根據構造函數參數的數據類型,進行byType模式的自動裝配。no默認值,不使用自動裝配,Bean依賴必須通過<ref>元素或ref屬性定義。自動裝配38自動裝配,使用方式如下:JDBC驅動器:由數據庫廠商創建,也稱為JDBC驅動程序。負責與特定的數據庫連接,以及處理通信細節。修改上一節UserServiceImple和UserController,分別增加類屬性的setter方法;修改Spring配置文件,使用autowire屬性配置Bean;重新測試程序。<beanid="userDao"class="com.test.annotation.UserDaoImpl"/><beanid="userService"class="com.test.annotation.UserServiceImpl"autowire="byName"/><beanid="userController"class="com.test.annotation.UserController"autowire="byName"/>Bean的作用域06第7章SpringBean作用域的種類40

Spring中為Bean的實例定義了7種作用域,如下表所示:

注意:在上表7種作用域中,singleton和prototype是最常用的兩種作用域。作用域名城描述singleton單例模式。在單例模式下,Spring容器中只會存在一個共享的Bean實例,所有對Bean的請求,只要請求的id(或name)與Bean的定義相匹配,會返回Bean的同一個實例。prototype

原型模式,每次從容器中請求Bean時,都會產生一個新的實例。request每一個HTTP請求都會有自己的Bean實例,該作用域只能在基于Web的SpringApplicationContext中使用。session每一個HTTPsession請求都會有自己的Bean實例,該作用域只能在基于Web的SpringApplicationContext中使用。globalsession限定一個Bean的作用域為Web應用(HTTPsession)的生命周期,只有在Web應用中使用Spring時,該作用域才有效。

Spring中Bean的作用域41singleton與prototype區別:示例新實例getBean()getBean()getBean()新實例新實例<beanid="user"

class="cn.pojo.User"

scope="prototype"/>示例<beanid="user"

class="cn.pojo.User"

scope="singleton"/>

在Spring配置文件中,可以使用<bean>元素的scope屬性,將Bean的作用域定義成singleton。singleton作用域42

singleton是Spring容器默認的作用域,當Bean的作用域為singleton時,Spring容器就只會存在一個共享的Bean實例。singleton作用域對于無會話狀態的Bean(如Dao組件、Service組件)來說,是最理想的選擇。例如:<beanid="scope"class="com.test.scope.Scope"scope="singleton"/>

在Spring中如何配置singleton作用域?

在Spring配置文件中,同樣使用<bean>元素的scope屬性,將Bean的作用域定義成prototype。prototype作用域43

對需要保持會話狀態的Bean(如Struts2的Action類)應該使用prototype作用域。在使用prototype作用域時,Spring容器會為每個對該Bean的請求都創建一個新的實例。例如:<beanid="scope"class="com.test.scope.Scope"scope="prototype"/>

在Spring中如何配置prototype作用域?Bean的生命周期07第7章SpringBean了解Spring中Bean的生命周期有何意義?Bean的生命周期45了解Spring中Bean的生命周期的意義就在于,可以利用Bean在其存活期間的特定時刻完成一些相關操作。這種時刻可能有很多,但一般情況下,常會在Bean的postinitiation(初始化后)和predestruction(銷毀前)執行一些相關操作。Bean的生命周期46Spring容器可以管理singleton作用域的Bean的生命周期,在此作用域下,Spring能夠精確的知道該Bean何時被創建,何時初始化完成,以及何時被銷毀。singleton作用域prototype作用域的Bean,Spring只負責創建,當容器創建了Bean實例后,Bean的實例就交給客戶端代碼來管理,Spring容器將不再跟蹤其生命周期。prototype作用域Bean的生命周期管理

Spring容器可以管理Bean部分作用域的生命周期。有關說明具體如下:Bean的生命周期47Spring容器中Bean的生命周期流程如下圖所示;實例化Bean設置屬性值調用BeanNameAware的setBeanName()方法調用BeanFactoryAware的setBeanFactory()方法調用ApplicationContextAware的setApplicationContext()方法調用BeanPostProcessor的預初始化方法調用InitializingBean的afterPropertiesSet()方法調用定制的初始化方法調用BeanPsotProcessor的初始化方法Spring緩沖池中準備就緒的Bean將準備就緒的Bean交給調用者

調用Disposable的destory()方法調用destory-method屬性配置的銷毀方法?[Spring中Bean的銷毀][singleton][prototype]本章小結

本章主要講解了Spring對Bean的管理。首先介紹了SpringIoC容器,包括BeanFactory接口和ApplicationContext接口;其次講解了Bean的兩種配置方式,包括屬性setter方法注入和構造方法注入;接著講解了Bean的3種實例化方法,包括構造方法實例化、靜態工廠實例化和實例工廠實例化;然后講解了Bean的作用域,包括singleton作用域和prototype作用域;接著講解了Bean的3種裝配方式,包括基于XML的裝配、基于注解的裝配和自動裝配,最后講解了Bean的生命周期。通過本章的學習,讀者可以對Spring中Bean的管理有基本的了解,為以后框架開發奠定基礎。

本章小結48本章作業?

本章作業請簡述Bean的生命周期。請簡述Bean的幾種裝配方式的基本用法。?預習作業什么是AOP?Spring有哪些通知類型?49問題及作業集中問題&課后作業SpringAOP概述動態代理基于代理類的AOP實現基于XML的聲明式AspectJ基于注解的聲明式AspectJ第8章

SpringAOP2024/1/29學習目標/Target52了解AOP的概念和作用

理解AOP術語

熟悉Spring中兩種動態代理方式的區別

掌握基于代理類的AOP實現掌握基于XML的聲明式AspectJ和

基于注解的聲明式AspectJ章節概述/Summary53Spring的AOP模塊是Spring框架體系中十分重要的內容,該模塊一般適用于具有橫切邏輯的場景,如訪問控制、事務管理和性能監控等,本章將對SpringAOP的相關知識進行詳細講解。目錄/CONTENTSSpringAOP概述基于XML的聲明式AspectJ基于代理類的AOP實現動態代理54基于注解的聲明式AspectJ14325SpringAOP概述01第8章SpringAOP什么是AOP?SpringAOP簡介56

AOP的全稱是Aspect-OrientedProgramming,即面向切面編程(也稱面向方面編程)。它是面向對象編程(OOP)的一種補充,目前已成為一種比較成熟的編程方式。在傳統的業務處理代碼中,通常都會進行事務處理、日志記錄等操作。雖然使用OOP可以通過組合或者繼承的方式來達到代碼的重用,但如果要實現某個功能(如日志記錄),同樣的代碼仍然會分散到各個方法中。這樣,如果想要關閉某個功能,或者對其進行修改,就必須要修改所有的相關方法。這不但增加了開發人員的工作量,而且提高了代碼的出錯率。為了解決這一問題,AOP思想隨之產生。AOP采取橫向抽取機制,將分散在各個方法中的重復代碼提取出來,然后在程序編譯或運行時,再將這些提取出來的代碼應用到需要執行的地方。這種采用橫向抽取機制的方式,采用傳統的OOP思想顯然是無法辦到的,因為OOP只能實現父子關系的縱向的重用。雖然AOP是一種新的編程思想,但卻不是OOP的替代品,它只是OOP的延伸和補充。SpringAOP簡介57未使用AOP的面向切面編程案例

例如,訂單系統中有添加訂單信息、更新訂單信息和刪除訂單信息3個方法,這3個方法中都包含事務管理業務代碼,訂單系統的邏輯如圖所示。Spring

AOP概述58SpringAOP簡介59

AOP的使用,使開發人員在編寫業務邏輯時可以專心于核心業務,而不用過多的關注于其他業務邏輯的實現,這不但提高了開發效率,而且增強了代碼的可維護性。類與切面的關系AOP面向切面編程的優勢

由訂單系統可知,添加訂單信息、修改訂單信息、刪除訂單信息的方法體中都包含事務管理的業務邏輯,這就帶來了一定數量的重復代碼并使程序的維護成本增加。基于AOP的面向切面編程,可以為此類問題提供解決方案,AOP可以將事務管理的業務邏輯從這三個方法體中抽取到一個可重用的模塊,進而降低橫向業務邏輯之間的耦合,減少重復代碼。AOP的使用,使開發人員在編寫業務邏輯時可以專心于核心業務,而不用過多地關注其他業務邏輯的實現,不但提高了開發效率,又增強了代碼的可維護性。Spring

AOP概述60AOP術語61Aspect:封裝的用于橫向插入系統功能(如事務、日志等)的類Joinpoint:在程序執行過程中的某個階段點Pointcut:切面與程序流程的交叉點,即那些需要處理的連接點Advice(通知/增強處理):AOP框架在特定的切入點執行的增強處理,即在定義好的切入點處所要執行的程序代碼。可以將其理解為切面類中的方法。TargetObject(目標對象):指所有被通知的對象,也被稱為被增強對象。如果AOP框架采用的是動態的AOP實現,那么該對象就是一個被代理對象。Proxy(代理):將通知應用到目標對象之后,被動態創建的對象。Weaving(織入):將切面代碼插入到目標對象上,從而生成代理對象的過程。AOP術語

AOP并不是一個新的概念,AOP中涉及很多術語,如切面、連接點、切入點、通知/增強處理、目標對象、織入、代理和引介等,下面針對AOP的常用術語進行簡單介紹。

Spring

AOP術語切面(Aspect)切面是指關注點形成的類(關注點是指類中重復的代碼),通常是指封裝的、用于橫向插入系統的功能類(如事務管理、日志記錄等)。在實際開發中,該類被Spring容器識別為切面,需要在配置文件中通過<bean>元素指定。連接點(Joinpoint)連接點是程序執行過程中某個特定的節點,例如,某方法調用時或處理異常時。在SpringAOP中,一個連接點通常是一個方法的執行。

切入點(Pointcut)當某個連接點滿足預先指定的條件時,AOP就能夠定位到這個連接點,在連接點處插入切面,該連接點也就變成了切入點。通知/增強處理(Advice)通知/增強處理就是插入的切面程序代碼。可以將通知/增強處理理解為切面中的方法,它是切面的具體實現。62AOP術語

AOP并不是一個新的概念,AOP中涉及很多術語,如切面、連接點、切入點、通知/增強處理、目標對象、織入、代理和引介等,下面針對AOP的常用術語進行簡單介紹。

Spring

AOP術語目標對象(Target)目標對象是指被插入切面的方法,即包含主業務邏輯的類對象。或者說是被一個或者多個切面所通知的對象。織入(Weaving)將切面代碼插入到目標對象上,從而生成代理對象的過程。織入可以在編譯時,類加載時和運行時完成。在編譯時進行織入就是靜態代理,而在運行時進行織入則是動態代理。代理(Proxy)將通知應用到目標對象之后,程序動態創建的通知對象,就稱為代理。代理類既可能是和原類具有相同接口的類,也可能就是原類的子類,可以采用調用原類相同的方式調用代理類。引介(Introduction)引介是一種特殊的通知,它為目標對象添加一些屬性和方法。這樣,即使一個業務類原本沒有實現某一個接口,通過AOP的引介功能,也可以動態地為該業務類添加接口的實現邏輯,讓業務類成為這個接口的實現類。63動態代理02第8章SpringAOPJDK動態代理65

JDK動態代理是通過java.lang.reflect.Proxy

類來實現的,我們可以調用Proxy類的newProxyInstance()方法來創建代理對象。對于使用業務接口的類,Spring默認會使用JDK動態代理來實現AOP。CGLIB代理66

通過前面的學習可知,JDK的動態代理用起來非常簡單,但它是有局限性的,使用動態代理的對象必須實現一個或多個接口。

那么,如何代理沒有實現接口的類?CGLIB代理67

CGLIB(CodeGenerationLibrary)是一個高性能開源的代碼生成包,它采用非常底層的字節碼技術,對指定的目標類生成一個子類,并對子類進行增強。

如果想代理沒有實現接口的類,那么可以使用CGLIB代理。

JDK動態代理存在缺陷,它只能為接口創建代理對象,當需要為類創建代理對象時,就需要使用CGLib(CodeGenerationLibrary)動態代理,CGLib動態代理不要求目標類實現接口,它采用底層的字節碼技術,通過繼承的方式動態創建代理對象。Spring的核心包已經集成了CGLib所需要的包,所以開發中不需要另外導入JAR包。JDK與CGLib動態代理的比較68實現JDK動態代理與CGLIB動態代理的使用69需求說明使用JDK動態代理與CGLIB動態代理,對業務方法的執行過程進行模擬權限檢查、日志記錄。共性問題集中講解70常見問題及解決辦法代碼規范問題調試技巧共性問題集中講解基于代理類的AOP實現03第8章SpringAOPSpring的通知/增強類型72org.springframework.aop.MethodBeforeAdvice(前置通知/增強)

在目標方法執行前實施增強,可以應用于權限管理等功能。org.springframework.aop.AfterReturningAdvice(后置通知/增強)

在目標方法執行后實施增強,可以應用于關閉流、上傳文件、刪除

臨時文件等功能。ercept.MethodInterceptor(環繞通知/增強)

在目標方法執行前后實施增強,可以應用于日志、事務管理等功能。org.springframework.aop.ThrowsAdvice(異常拋出通知/增強)

在方法拋出異常后實施增強,可以應用于處理異常記錄日志等功能。org.springframework.aop.IntroductionInterceptor(引介通知/增強)

在目標類中添加一些新的方法和屬性,可以應用于修改老版本程序。

Spring按照通知在目標類方法的連接點位置,可以分為5種類型,具體如下:ProxyFactoryBean73

ProxyFactoryBean是FactoryBean接口的實現類,FactoryBean負責實例化一個Bean,而ProxyFactoryBean負責為其他Bean創建代理實例。在Spring中,使用ProxyFactoryBean是創建AOP代理的基本方式。ProxyFactoryBean類中的常用可配置屬性如下:使用基于代理類的AOP實現模擬權限檢查、

日志記錄功能74需求說明使用基于代理類的AOP對業務方法的執行過程進行模擬權限檢查、日志記錄。共性問題集中講解75常見問題及解決辦法代碼規范問題調試技巧共性問題集中講解基于XML的

聲明式AspectJ04第8章SpringAOPAspectJ開發77

AspectJ是一個基于Java語言的AOP框架,它提供了強大的AOP功能。Spring2.0以后,SpringAOP引入了對AspectJ的支持,并允許直接使用AspectJ進行編程,而Spring自身的AOPAPI也盡量與AspectJ保持一致。新版本的Spring框架,也建議使用AspectJ來開發AOP。使用AspectJ實現AOP有兩種方式:一種是基于XML的聲明式AspectJ,另一種是基于注解的聲明式AspectJ。概述使用AOP代理對象的好處

因為SpringAOP中的代理對象由IoC容器自動生成,所以開發者無須過多關注代理對象生成的過程,只需選擇連接點、創建切面、定義切點并在XML文件中添加配置信息即可。Spring提供了一系列配置SpringAOP的XML元素。

基于XMl的AOP實現78配置SpringAOP的XML元素79元素描述<aop:config>SpringAOP配置的根元素<aop:aspect>配置切面<aop:advisor>配置通知器<aop:pointcut>配置切點<aop:before>配置前置通知,在目標方法執行前實施增強,可以應用于權限管理等功能<aop:after>配置后置通知,在目標方法執行后實施增強,可以應用于關閉流、上傳文件、刪除臨時文件等功能<aop:around>配置環繞方式,在目標方法執行前后實施增強,可以應用于日志、事務管理等功能<aop:after-returning>配置返回通知,在目標方法成功執行之后調用通知<aop:after-throwing>配置異常通知,在方法拋出異常后實施增強,可以應用于處理異常記錄日志等功能基于XML的聲明式AspectJ是指通過XML文件來定義切面、切入點及通知,所有的切面、切入點和通知都必須定義在<aop:config>元素內。基于XML的聲明式AspectJ80<aop:config>元素及其子元素如下:小提示:圖中灰色部分標注的元素即為常用的配置元素

XML文件中常用元素的配置方式如下:基于XML的聲明式AspectJ81<beanid="myAspect"class="com.test.aspectj.xml.MyAspect"/><aop:config><aop:aspectid="aspect"ref="myAspect"><aop:pointcutexpression="execution(*com.test.jdk.*.*(..))“id="myPointCut"/><aop:beforemethod="myBefore"pointcut-ref="myPointCut"/><aop:after-returningmethod="myAfterReturning“pointcut-ref="myPointCut" returning="returnVal"/><aop:aroundmethod="myAround"pointcut-ref="myPointCut"/><aop:after-throwingmethod="myAfterThrowing“pointcut-ref="myPointCut" throwing="e"/><aop:aftermethod="myAfter"pointcut-ref="myPointCut"/></aop:aspect></aop:config>定義切面Bean配置切面配置切入點配置通知配置切面

在Spring的配置文件中,配置切面使用的是<aop:aspect>元素,該元素會將一個已定義好的SpringBean轉換成切面Bean,因此,在使用<aop:aspect>元素之前,要在配置文件中先定義一個普通的SpringBean。SpringBean定義完成后,通過<aop:aspect>元素的ref屬性即可引用該Bean。配置<aop:aspect>元素時,通常會指定id和ref兩個屬性。

基于XML的聲明式AspectJ82<aop:aspect>元素的id屬性和ref屬性的描述基于XML的聲明式AspectJ83屬性名稱描述id用于定義該切面的唯一標識ref用于引用普通的SpringBean配置切入點

在Spring的配置文件中,切入點是通過<aop:pointcut>元素來定義的。當<aop:pointcut>元素作為<aop:config>元素的子元素定義時,表示該切入點是全局的,它可被多個切面共享;當<aop:pointcut>元素作為<aop:aspect>元素的子元素時,表示該切入點只對當前切面有效。定義<aop:pointcut>元素時,通常會指定id、expression屬性。

基于XML的聲明式AspectJ84<aop:pointcut>元素的id屬性和expression屬性描述基于XML的聲明式AspectJ85屬性名稱描述id用于指定切入點的唯一標識expression用于指定切入點關聯的切入點表達式基于XML的聲明式AspectJ86切入點表達式

execution(*

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論