日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

spring基础知识(IOC、DI、AOP)

發(fā)布時(shí)間:2023/12/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 spring基础知识(IOC、DI、AOP) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

一、spring概述

二、spring核心功能 ioc控制反轉(zhuǎn)

1、什么是IOC

2、為什么要使用IOC

3、IOC的技術(shù)實(shí)現(xiàn)——DI依賴注入

? ? ?3.1Spring的第一個(gè)程序——spring創(chuàng)建對(duì)象的步驟

? ? ?3.2 DI依賴注入

? ?3.2.1基于XML的DI

? ?3.2.2基于注解的DI

? ?3.2.3注解與XML對(duì)比

四、面向切面編程AOP

4.1 概述

4.1.1動(dòng)態(tài)代理的實(shí)現(xiàn)方式

4.1.2 動(dòng)態(tài)代理的作用

4.1.3 AOP概述

4.1.4 AOP的實(shí)現(xiàn)

4.1.5 AOP的好處

4.2 AspectJ對(duì)AOP的實(shí)現(xiàn)

4.2.1 AspectJ切入點(diǎn)表達(dá)式

4.2.2 AspectJ 基于注解的 AOP 實(shí)現(xiàn)


一、spring概述

?Spring 的主要作用就是為代碼“解耦”,降低代碼間的耦合度。就是讓對(duì)象和對(duì)象(模塊和模塊)之間關(guān)系不是使用代碼關(guān)聯(lián),而是通過(guò)配置來(lái)說(shuō)明。減輕對(duì)項(xiàng)目模塊之間的管理,?類和類之間的管理, 幫助開(kāi)發(fā)人員創(chuàng)建對(duì)象,管理對(duì)象之間的關(guān)系。
Spring 根據(jù)代碼的功能特點(diǎn),使用 Ioc 降低業(yè)務(wù)對(duì)象之間耦合度。IoC 使得主業(yè)務(wù)在相互調(diào)用過(guò)程中,不用再自己維護(hù)關(guān)系了,即不用再自己創(chuàng)建要使用的對(duì)象了。而是由 Spring容器統(tǒng)一管理,自動(dòng)“注入”,注入即賦值。 而 AOP 使得系統(tǒng)級(jí)服務(wù)得到了最大復(fù)用,且不用再由程序員手工將系統(tǒng)級(jí)服務(wù)“混雜”到主業(yè)務(wù)邏輯中了,而是由 Spring 容器統(tǒng)一完成“織入”。

二、spring核心功能 ioc控制反轉(zhuǎn)

1、什么是IOC

控制: 創(chuàng)建對(duì)象,對(duì)象的屬性賦值,對(duì)象之間的關(guān)系管理。
反轉(zhuǎn): 把原來(lái)的開(kāi)發(fā)人員管理,創(chuàng)建對(duì)象的權(quán)限轉(zhuǎn)移給代碼之外的容器實(shí)現(xiàn)。 由容器代替開(kāi)發(fā)人員管理對(duì)象。創(chuàng)建對(duì)象,給屬性賦值。

IOC:把對(duì)象的創(chuàng)建,賦值,管理工作都交給代碼之外的容器實(shí)現(xiàn), 也就是對(duì)象的創(chuàng)建是有其它外部資源完成。

2、為什么要使用IOC

目的就是減少對(duì)代碼的改動(dòng), 也能實(shí)現(xiàn)不同的功能。 實(shí)現(xiàn)解耦合。?

3、IOC的技術(shù)實(shí)現(xiàn)——DI依賴注入

Spring 容器是一個(gè)超級(jí)大工廠,負(fù)責(zé)創(chuàng)建、管理所有的 Java 對(duì)象,這些 Java 對(duì)象被稱為 Bean。Spring 容器管理著容器中 Bean 之間的依賴關(guān)系,Spring 使用“依賴注入”的方式來(lái)管理 Bean 之間的依賴關(guān)系。使用 IoC 實(shí)現(xiàn)對(duì)象之間的解耦和。spring是使用的di實(shí)現(xiàn)了ioc的功能, spring底層創(chuàng)建對(duì)象,使用的是反射機(jī)制

3.1Spring的第一個(gè)程序——spring創(chuàng)建對(duì)象的步驟

1.創(chuàng)建maven項(xiàng)目


2.加入maven的依賴
? spring的依賴,版本5.2.5版本【spring-context】
? junit依賴【junit】


3.創(chuàng)建類(接口和它的實(shí)現(xiàn)類)
? 和沒(méi)有使用框架一樣, 就是普通的類。

4.創(chuàng)建spring需要使用的配置文件
? 在 src/main/resources/目錄現(xiàn)創(chuàng)建一個(gè) xml 文件,文件名可以隨意,但 Spring 建議的名稱為 applicationContext.xml。聲明類的信息,這些類由spring創(chuàng)建和管理

實(shí)例化方式

(一)默認(rèn)構(gòu)造 <bean? id="" class=""/>:用于定義一個(gè)實(shí)例對(duì)象。一個(gè)實(shí)例對(duì)應(yīng)一個(gè) bean 元素。
id:該屬性是 Bean 實(shí)例的唯一標(biāo)識(shí),程序通過(guò) id 屬性訪問(wèn) Bean,Bean 與 Bean 間的依賴關(guān)系也是通過(guò) id 屬性關(guān)聯(lián)的。
class:指定該 Bean 所屬的類,注意這里只能是類,不能是接口

(二)靜態(tài)工廠<bean id="" class="工廠類" factory-method="靜態(tài)方法">

靜態(tài)工廠:用于生成實(shí)例對(duì)象,所有的方法必須是static

public class MyBeanFactory {public static UserService createService(){return new UserServiceImpl();} } <!-- 將靜態(tài)工廠創(chuàng)建的實(shí)例交予spring class 確定靜態(tài)工廠全限定類名factory-method 確定靜態(tài)方法名--><bean id="userServiceId" class="com.itheima.c_inject.b_static_factory.MyBeanFactory" factory-method="createService"></bean>

(三)實(shí)例工廠:<bean id="工廠id" class="工廠類">? <bean id="" factory-bean="工廠id" factory-method="方法">

必須先有工廠實(shí)例對(duì)象,通過(guò)實(shí)例對(duì)象創(chuàng)建對(duì)象。提供所有的方法都是“非靜態(tài)”的。

<!-- 創(chuàng)建工廠實(shí)例 --><bean id="myBeanFactoryId" class="com.itheima.c_inject.c_factory.MyBeanFactory"></bean><!-- 獲得userservice * factory-bean 確定工廠實(shí)例* factory-method 確定普通方法--><bean id="userServiceId" factory-bean="myBeanFactoryId" factory-method="createService"></bean>

?

5.測(cè)試spring創(chuàng)建的類

若 Spring 配置文件存放在項(xiàng)目的類路徑下,則使用 ClassPathXmlApplicationContext 實(shí)現(xiàn)類進(jìn)行加載。

測(cè)試方法規(guī)范:

? ? ?1)public 方法
?? ? 2)沒(méi)有返回值 void?
?? ? 3)方法名稱自定義,建議名稱是test + 你要測(cè)試方法名稱
?? ? 4)方法沒(méi)有參數(shù)
?? ? 5)方法的上面加入 @Test ,這樣的方法是可以單獨(dú)執(zhí)行的。 不用使用main方法。

3.2 DI依賴注入

di:依賴注入,表示創(chuàng)建對(duì)象,給屬性賦值。

di的實(shí)現(xiàn)有兩種:
1.在spring的配置文件中, 使用標(biāo)簽和屬性完成,叫做基于XML的di實(shí)現(xiàn)
2.使用spring中的注解,完成屬性賦值, 叫做基于注解的id實(shí)現(xiàn)

di的語(yǔ)法分類:
?1. set注入(設(shè)置注入): spring調(diào)用類的set方法,在set方法可以實(shí)現(xiàn)屬性的賦值。
?2. 構(gòu)造注入,spring調(diào)用類的有參數(shù)構(gòu)造方法,創(chuàng)建對(duì)象。在構(gòu)造方法中完成賦值。

3.2.1基于XML的DI

(1)set注入

set 注入也叫設(shè)值注入是指,通過(guò) setter 方法傳入被調(diào)用者的實(shí)例。這種注入方式簡(jiǎn)單、直觀,因而在 Spring 的依賴注入中大量使用

需要有set方法,沒(méi)有set方法是報(bào)錯(cuò)的。并且調(diào)用的是默認(rèn)的無(wú)參構(gòu)造函數(shù),如果重寫(xiě)了構(gòu)造函數(shù),一定要手動(dòng)加入無(wú)參的構(gòu)造函數(shù)才可

set注入(設(shè)值注入) :spring調(diào)用類的set方法, 你可以在set方法中完成屬性賦值
? ? ? ? ?1)簡(jiǎn)單類型的set注入
? ? ? ? ? ? <bean id="xx" class="yyy">
? ? ? ? ? ? ? ?<property name="屬性名字" value="此屬性的值"/>
? ? ? ? ? ? ? ?一個(gè)property只能給一個(gè)屬性賦值
? ? ? ? ? ? ? ?<property....>
? ? ? ? ? ? </bean>

? ? ? ? ?2) 引用類型的set注入 : spring調(diào)用類的set方法
? ? ? ? ? ?<bean id="xxx" class="yyy">
? ? ? ? ? ? ? <property name="屬性名稱" ref="bean的id(對(duì)象的名稱)" />
? ? ? ? ? ?</bean>

(2)構(gòu)造注入

構(gòu)造注入是指,在構(gòu)造調(diào)用者實(shí)例的同時(shí),完成被調(diào)用者的實(shí)例化。即,使用構(gòu)造器設(shè)置依賴關(guān)系。

構(gòu)造注入:spring調(diào)用類有參數(shù)構(gòu)造方法,在創(chuàng)建對(duì)象的同時(shí),在構(gòu)造方法中給屬性賦值。構(gòu)造注入使用 <constructor-arg> 標(biāo)簽
? ? ? ? ? <constructor-arg> 標(biāo)簽:一個(gè)<constructor-arg>表示構(gòu)造方法一個(gè)參數(shù)
? ? ? ? ? <constructor-arg> 標(biāo)簽屬性:
? ? ? ? ? ? ?name:表示構(gòu)造方法的形參名
? ? ? ? ? ? ?index:表示構(gòu)造方法的參數(shù)的位置,參數(shù)從左往右位置是 0 , 1 ,2的順序
? ? ? ? ? ? ?value:構(gòu)造方法的形參類型是簡(jiǎn)單類型的,使用value
? ? ? ? ? ? ?ref:構(gòu)造方法的形參類型是引用類型的,使用ref

(3)引用類型的自動(dòng)注入

對(duì)于引用類型屬性的注入,也可不在配置文件中顯示的注入。可以通過(guò)為<bean/>標(biāo)簽,設(shè)置 autowire 屬性值,為引用類型屬性進(jìn)行隱式自動(dòng)注入(默認(rèn)是不自動(dòng)注入引用類型屬
性)。根據(jù)自動(dòng)注入判斷標(biāo)準(zhǔn)的不同,可以分為兩種:

  • byName:根據(jù)名稱自動(dòng)注入
  • byType: 根據(jù)類型自動(dòng)注入

引用類型的自動(dòng)注入: spring框架根據(jù)某些規(guī)則可以給引用類型賦值。·不用你在給引用類型賦值了
? ? ? ?使用的規(guī)則常用的是byName, byType.
? ? ? ?1.byName(按名稱注入) : java類中引用類型的屬性名和spring容器中(配置文件)<bean>的id名稱一樣,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 且數(shù)據(jù)類型是一致的,這樣的容器中的bean,spring能夠賦值給引用類型。
? ? ? ? ?語(yǔ)法:
? ? ? ? ?<bean id="xx" class="yyy" autowire="byName">
? ? ? ? ? ? 簡(jiǎn)單類型屬性賦值
? ? ? ? ?</bean>

? ? ? ?2.byType(按類型注入) : java類中引用類型的數(shù)據(jù)類型和spring容器中(配置文件)<bean>的class屬性
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 是同源關(guān)系的
,這樣的bean能夠賦值給引用類型
? ? ? ? ?同源就是一類的意思:
? ? ? ? ? 1.java類中引用類型的數(shù)據(jù)類型和bean的class的值是一樣的。
? ? ? ? ? 2.java類中引用類型的數(shù)據(jù)類型和bean的class的值父子類關(guān)系的。
? ? ? ? ? 3.java類中引用類型的數(shù)據(jù)類型和bean的class的值接口和實(shí)現(xiàn)類關(guān)系的
? ? ? ? ?語(yǔ)法:
? ? ? ? ?<bean id="xx" class="yyy" autowire="byType">
? ? ? ? ? ? 簡(jiǎn)單類型屬性賦值
? ? ? ? ?</bean>

注意:在byType中, 在xml配置文件中聲明bean只能有一個(gè)符合條件的,多余一個(gè)是錯(cuò)誤的

(4)集合類型注入

<bean id="collDataId" class="com.itheima.f_xml.e_coll.CollData" ><property name="arrayData"><array><value>DS</value><value>DZD</value><value>屌絲</value><value>屌中屌</value></array></property><property name="listData"><list><value>于嵩楠</value><value>曾衛(wèi)</value><value>楊煜</value><value>曾小賢</value></list></property><property name="setData"><set><value>停封</value><value>薄紙</value><value>關(guān)系</value></set></property><property name="mapData"><map><entry key="jack" value="杰克"></entry><entry><key><value>rose</value></key><value>肉絲</value></entry></map></property><property name="propsData"><props><prop key="高富帥">嫐</prop><prop key="白富美">嬲</prop><prop key="男屌絲">挊</prop></props></property></bean>

集合的注入都是給<property>添加子標(biāo)簽
??????????????數(shù)組:<array>
?????????????????????List:<list>
?????????????????????Set:<set>
?????????????????????Map:<map>?,map存放k?鍵值對(duì),使用<entry>描述
?????????????????????Properties:<props>??<prop?key=""></prop>??
??????????????普通數(shù)據(jù):<value>
??????????????引用數(shù)據(jù):<ref>

(5)為應(yīng)用指定多個(gè)spring配置文件

在實(shí)際應(yīng)用里,隨著應(yīng)用規(guī)模的增加,系統(tǒng)中 Bean 數(shù)量也大量增加,導(dǎo)致配置文件變得非常龐大、臃腫。為了避免這種情況的產(chǎn)生,提高配置文件的可讀性與可維護(hù)性,可以將
Spring 配置文件分解成多個(gè)配置文件。

包含關(guān)系的配置文件:多個(gè)配置文件中有一個(gè)總文件,總配置文件將各其它子文件通過(guò)<import/>引入。在 Java代碼中只需要使用總配置文件對(duì)容器進(jìn)行初始化即可。

包含關(guān)系的配置文件:
? ? ? ? ?spring-total表示主配置文件 : 包含其他的配置文件的,主配置文件一般是不定義對(duì)象的。
? ? ? ? ?語(yǔ)法:<import resource="其他配置文件的路徑" />
? ? ? ? ?關(guān)鍵字:"classpath:" 表示類路徑(class文件所在的目錄),
? ? ? ? ? ? ? ?在spring的配置文件中要指定其他文件的位置, 需要使用classpath,告訴spring到哪去加載讀取文件。

? ? ? ?在包含關(guān)系的配置文件中,可以通配符(*:表示任意字符)
? ? ? ?注意: 主的配置文件名稱不能包含在通配符的范圍內(nèi)

3.2.2基于注解的DI

(1)?定義 Bean 的注解@Component

@Component: 創(chuàng)建對(duì)象的, 等同于<bean>的功能
?? ? ?屬性:value 就是對(duì)象的名稱,也就是bean的id值,
?? ? ? ? ? value的值是唯一的,創(chuàng)建的對(duì)象在整個(gè)spring容器中就一個(gè)
?? ? 位置:在類的上面
?
?? @Component(value = "myStudent")等同于
?? ?<bean id="myStudent" class="com.bjpowernode.ba01.Student" />
?
?? spring中和@Component功能一致,創(chuàng)建對(duì)象的注解還有:
?? 1.@Repository(用在持久層類的上面) : 放在dao的實(shí)現(xiàn)類上面,
?? ? ? ? ? ? ? ?表示創(chuàng)建dao對(duì)象,dao對(duì)象是能訪問(wèn)數(shù)據(jù)庫(kù)的。
?? 2.@Service(用在業(yè)務(wù)層類的上面):放在service的實(shí)現(xiàn)類上面,
?? ? ? ? ? ? ?創(chuàng)建service對(duì)象,service對(duì)象是做業(yè)務(wù)處理,可以有事務(wù)等功能的。
?? 3.@Controller(用在控制器的上面):放在控制器(處理器)類的上面,創(chuàng)建控制器對(duì)象的,
?? ? ? ? ? ? ? 控制器對(duì)象,能夠接受用戶提交的參數(shù),顯示請(qǐng)求的處理結(jié)果。
?? 以上三個(gè)注解的使用語(yǔ)法和@Component一樣的。 都能創(chuàng)建對(duì)象,但是這三個(gè)注解還有額外的功能。
?? @Repository,@Service,@Controller是給項(xiàng)目的對(duì)象分層的。

(2) 簡(jiǎn)單 類型屬性注入@Value
使用該注解完成屬性注入時(shí),類中無(wú)需 setter。當(dāng)然,若屬性有 setter,則也可將其加到 setter 上。

?@Value: 簡(jiǎn)單類型的屬性賦值
? ? ?? ?屬性: value 是String類型的,表示簡(jiǎn)單類型的屬性值
? ? ?? ?位置: 1.在屬性定義的上面,無(wú)需set方法,推薦使用。
? ? ?? ? ? ? ? ? ? ?2.在set方法的上面

(3)byType 自動(dòng)注入@Autowired
使用該注解完成屬性注入時(shí),類中無(wú)需 setter。當(dāng)然,若屬性有 setter,則也可將其加到 setter 上。

?引用類型
? ? ??@Autowired: spring框架提供的注解,實(shí)現(xiàn)引用類型的賦值。
? ? ??spring中通過(guò)注解給引用類型賦值,使用的是自動(dòng)注入原理 ,支持byName, byType
? ? ??@Autowired:默認(rèn)使用的是byType自動(dòng)注入
? ? ?
? ? ?? 位置:1)在屬性定義的上面,無(wú)需set方法, 推薦使用
? ? ?? ? ? ? ? ? ?2)在set方法的上面

(4)byName 自動(dòng)注入@Autowired 與@Qualifier

引用類型

如果要使用byName方式,需要做的是:
? ? ?? 1.在屬性上面加入@Autowired
? ? ?? 2.在屬性上面加入@Qualifier(value="bean的id") :表示使用指定名稱的bean完成賦值。

屬性:required ,是一個(gè)boolean類型的,默認(rèn)true
? ? ? ? ? ?required=true:表示引用類型賦值失敗,程序報(bào)錯(cuò),并終止執(zhí)行。
? ? ? ? ? required=false:引用類型如果賦值失敗, 程序正常執(zhí)行,引用類型是null

(5)JDK 注解@Resource 自動(dòng)注入

?引用類型
? ? ??@Resource: 來(lái)自jdk中的注解,spring框架提供了對(duì)這個(gè)注解的功能支持,可以使用它給引用類型賦值
? ? ? ? ? ? ? 使用的也是自動(dòng)注入原理,支持byName, byType .默認(rèn)是byName
? ? ?? 位置: 1.在屬性定義的上面,無(wú)需set方法,推薦使用。
? ? ?? ? ? ? ? ? ? 2.在set方法的上面
默認(rèn)是byName: 先使用byName自動(dòng)注入,如果byName賦值失敗,再使用byType

小結(jié):

注入? --> 字段或setter方法

????????????? 普通值:@Value

????????????? 引用值:

???????????????????? 類型:@Autowired

???????????????????? 名稱1:@Autowired? @Qualifier("名稱")

???????????????????? 名稱2:@Resource("名稱")

3.2.3注解與XML對(duì)比

四、面向切面編程AOP

4.1 概述

4.1.1動(dòng)態(tài)代理的實(shí)現(xiàn)方式

jdk動(dòng)態(tài)代理使用jdk中的Proxy,Method,InvocaitonHanderl創(chuàng)建代理對(duì)象。
? ? ? ? ? ? ?jdk動(dòng)態(tài)代理要求目標(biāo)類必須實(shí)現(xiàn)接口

? cglib動(dòng)態(tài)代理:第三方的工具庫(kù),創(chuàng)建代理對(duì)象,原理是繼承。 通過(guò)繼承目標(biāo)類,創(chuàng)建子類
? ? ? ? ? ? ?子類就是代理對(duì)象。 要求目標(biāo)類不能是final的, 方法也不能是final的

4.1.2 動(dòng)態(tài)代理的作用

? ??1)在目標(biāo)類源代碼不改變的情況下,增加功能
?? ?2)減少代碼的重復(fù)
?? ?3)專注業(yè)務(wù)邏輯代碼
?? ?4)解耦合,讓你的業(yè)務(wù)功能和日志,事務(wù)非業(yè)務(wù)功能分離。

4.1.3 AOP概述

AOP 為 Aspect Oriented Programming 的縮寫(xiě),意為:面向切面編程,可通過(guò)運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP 是 Spring 框架中的一個(gè)重要內(nèi)容。利用 AOP
可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開(kāi)發(fā)的效率。

? Aspect: 切面,給你的目標(biāo)類增加的功能,就是切面。 像上面用的日志,事務(wù)都是切面。
? ? ? ? ? 切面的特點(diǎn): 一般都是非業(yè)務(wù)方法,獨(dú)立使用的。
? Orient:面向, 對(duì)著。
? Programming:編程

? oop: 面向?qū)ο缶幊?/p>

? 怎么理解面向切面編程 ??
? ?1)需要在分析項(xiàng)目功能時(shí),找出切面。
?? ?2)合理的安排切面的執(zhí)行時(shí)間(在目標(biāo)方法前, 還是目標(biāo)方法后)
?? ?3)合理的安全切面執(zhí)行的位置,在哪個(gè)類,哪個(gè)方法增加增強(qiáng)功能

? 術(shù)語(yǔ):
? ?1)Aspect:切面,表示增強(qiáng)的功能, 就是一堆代碼,完成某個(gè)一個(gè)功能。非業(yè)務(wù)功能,
?? ? ? ? ? ? ?常見(jiàn)的切面功能有日志, 事務(wù), 統(tǒng)計(jì)信息, 參數(shù)檢查, 權(quán)限驗(yàn)證。

? ?2)JoinPoint:連接點(diǎn) ,連接業(yè)務(wù)方法和切面的位置。 就某類中的業(yè)務(wù)方法
?? ?3)Pointcut : 切入點(diǎn) ,指多個(gè)連接點(diǎn)方法的集合。多個(gè)方法
?? ?4)目標(biāo)對(duì)象: 給哪個(gè)類的方法增加功能, 這個(gè)類就是目標(biāo)對(duì)象
?? ?5)Advice:通知,通知表示切面功能執(zhí)行的時(shí)間。

?? ?說(shuō)一個(gè)切面有三個(gè)關(guān)鍵的要素:
?? ?1)切面的功能代碼,切面干什么
?? ?2)切面的執(zhí)行位置,使用Pointcut表示切面執(zhí)行的位置
?? ?3)切面的執(zhí)行時(shí)間,使用Advice表示時(shí)間,在目標(biāo)方法之前,還是目標(biāo)方法之后。

4.1.4 AOP的實(shí)現(xiàn)

?aop是一個(gè)規(guī)范,是動(dòng)態(tài)的一個(gè)規(guī)范化,一個(gè)標(biāo)準(zhǔn)
?? ?aop的技術(shù)實(shí)現(xiàn)框架:
?? ?1.spring:spring在內(nèi)部實(shí)現(xiàn)了aop規(guī)范,能做aop的工作。
?? ? ? ? ? ? ?spring主要在事務(wù)處理時(shí)使用aop。
?? ??? ??? ??? ? 我們項(xiàng)目開(kāi)發(fā)中很少使用spring的aop實(shí)現(xiàn)。 因?yàn)閟pring的aop比較笨重。


? ?2.aspectJ: 一個(gè)開(kāi)源的專門(mén)做aop的框架。spring框架中集成了aspectj框架,通過(guò)spring就能使用aspectj的功能。
?? ? ?aspectJ框架實(shí)現(xiàn)aop有兩種方式:
?? ? ? 1.使用xml的配置文件 : 配置全局事務(wù)
?? ??? ?2.使用注解,我們?cè)陧?xiàng)目中要做aop功能,一般都使用注解, aspectj有5個(gè)注解。

4.1.5 AOP的好處

1.減少重復(fù);
2.專注業(yè)務(wù);
注意:面向切面編程只是面向?qū)ο缶幊痰囊环N補(bǔ)充。

4.2 AspectJ對(duì)AOP的實(shí)現(xiàn)

4.2.1 AspectJ切入點(diǎn)表達(dá)式

4.2.2 AspectJ 基于注解的 AOP 實(shí)現(xiàn)

AspectJ 中常用的通知有五種類型:
1)前置通知
2)后置通知
3)環(huán)繞通知
4)異常通知
5)最終通知

(1)實(shí)現(xiàn)步驟

@Aspect : 是aspectj框架中的注解。
? ? ? 作用:表示當(dāng)前類是切面類
? ? ? 切面類:是用來(lái)給業(yè)務(wù)方法增加功能的類,在這個(gè)類中有切面的功能代碼
? ? ? 位置:在類定義的上面

切面類中的方法定義規(guī)范
? ? ?定義方法,方法是實(shí)現(xiàn)切面功能的。
? ? ?方法的定義要求:
? ? ?1.公共方法 public
? ? ?2.方法沒(méi)有返回值
? ? ?3.方法名稱自定義
? ? ?4.方法可以有參數(shù),也可以沒(méi)有參數(shù)。
? ? ?? 如果有參數(shù),參數(shù)不是自定義的,有幾個(gè)參數(shù)類型可以使用。

@Before: 前置通知注解
? ? ?? ?屬性:value ,是切入點(diǎn)表達(dá)式,表示切面的功能執(zhí)行的位置。
? ? ?? ?位置:在方法的上面
? ? ??特點(diǎn):
? ? ?? 1.在目標(biāo)方法之前先執(zhí)行的
? ? ?? 2.不會(huì)改變目標(biāo)方法的執(zhí)行結(jié)果
? ? ?? 3.不會(huì)影響目標(biāo)方法的執(zhí)行。

指定通知方法中的參數(shù) : JoinPoint
? ? ??JoinPoint:業(yè)務(wù)方法,要加入切面功能的業(yè)務(wù)方法
? ? ?? ? 作用是:可以在通知方法中獲取方法執(zhí)行時(shí)的信息, 例如方法名稱,方法的實(shí)參。
? ? ?? ? 如果你的切面功能中需要用到方法的信息,就加入JoinPoint.
? ? ?? ?這個(gè)JoinPoint參數(shù)的值是由框架賦予, 必須是第一個(gè)位置的參數(shù)

后置通知定義方法,方法是實(shí)現(xiàn)切面功能的。
? ? ??方法的定義要求:
? ? ??1.公共方法 public
? ? ??2.方法沒(méi)有返回值
? ? ??3.方法名稱自定義
? ? ??4.方法有參數(shù)的,推薦是Object ,參數(shù)名自定義

@AfterReturning:后置通知
? ? ?? ? 屬性:1.value 切入點(diǎn)表達(dá)式
? ? ?? ? ? ? ?2.returning 自定義的變量,表示目標(biāo)方法的返回值的。
? ? ?? ? ? ? ? 自定義變量名必須和通知方法的形參名一樣。
? ? ?? ? 位置:在方法定義的上面
? ? ??特點(diǎn):
? ? ?? 1. 在目標(biāo)方法之后執(zhí)行的。
? ? ?? 2. 能夠獲取到目標(biāo)方法的返回值,可以根據(jù)這個(gè)返回值做不同的處理功能
? ? ? ? ? ?Object res = doOther();
? ? ? ?3. 可以修改這個(gè)返回值
? ??
? ? ?? 后置通知的執(zhí)行
? ? ?? ? Object res = doOther();
? ? ?? ? 參數(shù)傳遞: 傳值, 傳引用
? ? ?? ? myAfterReturing(res);
? ? ?? ? System.out.println("res="+res)

環(huán)繞通知方法的定義格式
? ? ?? 1.public
? ? ?? 2.必須有一個(gè)返回值,推薦使用Object
? ? ?? 3.方法名稱自定義
? ? ?? 4.方法有參數(shù),固定的參數(shù) ProceedingJoinPoint

@Around: 環(huán)繞通知
? ? ?? ? 屬性:value 切入點(diǎn)表達(dá)式
? ? ?? ? 位置:在方法的定義什么
? ? ?特點(diǎn):
? ? ?? ?1.它是功能最強(qiáng)的通知
? ? ?? ?2.在目標(biāo)方法的前和后都能增強(qiáng)功能。
? ? ?? ?3.控制目標(biāo)方法是否被調(diào)用執(zhí)行
? ? ?? ?4.修改原來(lái)的目標(biāo)方法的執(zhí)行結(jié)果。 影響最后的調(diào)用結(jié)果
? ?
? ? ?? 環(huán)繞通知,等同于jdk動(dòng)態(tài)代理的,InvocationHandler接口
? ? ?
? ? ?? 參數(shù): ?ProceedingJoinPoint 就等同于 Method
? ? ?? ? ? ? ?作用:執(zhí)行目標(biāo)方法的
? ? ?? 返回值: 就是目標(biāo)方法的執(zhí)行結(jié)果,可以被修改。
? ? ?? 環(huán)繞通知: 經(jīng)常做事務(wù), 在目標(biāo)方法之前開(kāi)啟事務(wù),執(zhí)行目標(biāo)方法, 在目標(biāo)方法之后提交事務(wù)

異常通知方法的定義格式
? ? ??1.public
? ? ?? 2.沒(méi)有返回值
? ? ?? 3.方法名稱自定義
? ? ?? 4.方法有個(gè)一個(gè)Exception, 如果還有是JoinPoint

??@AfterThrowing:異常通知
? ? ?? ? ?屬性:1. value 切入點(diǎn)表達(dá)式
? ? ?? ? ? ? ? 2. throwinng 自定義的變量,表示目標(biāo)方法拋出的異常對(duì)象。
? ? ?? ? ? ? ? ?? 變量名必須和方法的參數(shù)名一樣
? ? ??特點(diǎn):
? ? ?? ?1. 在目標(biāo)方法拋出異常時(shí)執(zhí)行的
? ? ?? 2. 可以做異常的監(jiān)控程序, 監(jiān)控目標(biāo)方法執(zhí)行時(shí)是不是有異常。
? ? ?? ? ? 如果有異常,可以發(fā)送郵件,短信進(jìn)行通知
? ? ?
? ? ?? 執(zhí)行就是:
? ? ?? ?try{
? ? ?? ? ? ?SomeServiceImpl.doSecond(..)
? ? ?? ?}catch(Exception e){
? ? ?? ? ? ?myAfterThrowing(e);
? ? ?? ?}

?最終通知方法的定義格式
? ? ?? 1.public
? ? ?? 2.沒(méi)有返回值
? ? ?? 3.方法名稱自定義
? ? ?? 4.方法沒(méi)有參數(shù), ?如果還有是JoinPoint

?@After :最終通知
? ? ?? ? 屬性: value 切入點(diǎn)表達(dá)式
? ? ?? ?位置: 在方法的上面
? ? ??特點(diǎn):
? ? ?? 1.總是會(huì)執(zhí)行
? ? ?? 2.在目標(biāo)方法之后執(zhí)行的
? ? ?
? ? ?? try{
? ? ?? ? ?SomeServiceImpl.doThird(..)
? ? ?? }catch(Exception e){
? ? ?
? ? ?? }finally{
? ? ?? ? ? myAfter()
? ? ??}

@Pointcut: 定義和管理切入點(diǎn), 如果你的項(xiàng)目中有多個(gè)切入點(diǎn)表達(dá)式是重復(fù)的,可以復(fù)用的
? ? ? ? ? ? ? ? ?可以使用@Pointcut
? ? ?? ? 屬性:value 切入點(diǎn)表達(dá)式
? ? ?? ?位置:在自定義的方法上面
? ? ??特點(diǎn):
? ? ?? ?當(dāng)使用@Pointcut定義在一個(gè)方法的上面 ,此時(shí)這個(gè)方法的名稱就是切入點(diǎn)表達(dá)式的別名
? ? ?? ?其它的通知中,value屬性就可以使用這個(gè)方法名稱,代替切入點(diǎn)表達(dá)式了

?

總結(jié)

以上是生活随笔為你收集整理的spring基础知识(IOC、DI、AOP)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。