javascript
快速入门Spring之SpringAOP
學(xué)習(xí)目標(biāo)
1、AOP簡(jiǎn)介 2、AOP在Spring中的實(shí)現(xiàn) 3、AOP的注解配置 4、AOP日志跟蹤案例1、AOP簡(jiǎn)介
1.1 AOP基本概念
AOP(Aspect Oriented Programming)面向切面編程,通過(guò)預(yù)編譯方式和運(yùn)行期間動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP是OOP的延續(xù),是軟件開(kāi)發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容。
1.2 AOP的作用
AOP的核心作用是:在程序運(yùn)行期間,不修改代碼的同時(shí)為程序增強(qiáng)功能。將必不可少的公共功能做成切面,隨著程序運(yùn)行切入到代碼中運(yùn)行。編寫業(yè)務(wù)時(shí)只關(guān)注于核心功能 ,不再考慮事務(wù)、日志等公共功能,減輕了編碼負(fù)擔(dān),更專注于業(yè)務(wù)。
解耦,分離核心業(yè)務(wù)和非核心業(yè)務(wù),非核心業(yè)務(wù)由AOP的切面實(shí)現(xiàn),用戶只需要關(guān)注核心業(yè)務(wù)。
1.3 AOP的術(shù)語(yǔ)
1、切面(Aspect)
對(duì)哪些方法進(jìn)行攔截,攔截后怎么處理,這些關(guān)注點(diǎn)稱之為切面
2、連接點(diǎn)(joinpoint)
被攔截到的點(diǎn),因?yàn)镾pring只支持方法類型的連接點(diǎn),所以在Spring中連接點(diǎn)指的就是被攔截到的方法,實(shí)際上連接點(diǎn)還可以是字段或者構(gòu)造器
3、切入點(diǎn)(pointcut)
對(duì)連接點(diǎn)進(jìn)行攔截的定義
4、通知(advice)
所謂通知指的就是指攔截到連接點(diǎn)之后要執(zhí)行的代碼,通知分為前置、后置、異常、最終、環(huán)繞通知五類
5、目標(biāo)對(duì)象(target)
代理的目標(biāo)對(duì)象,將切面應(yīng)用到目標(biāo)對(duì)象并導(dǎo)致代理對(duì)象創(chuàng)建的過(guò)程
6、引入\織入(introduction、weave)
在不修改代碼的前提下,引入可以在運(yùn)行期為類動(dòng)態(tài)地添加一些方法或字段
# 2、AOP的實(shí)現(xiàn)
2.1 AOP配置步驟
2.1.1 引入依賴
<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.2.8.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.9.5</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.5</version></dependency>2.1.2 編寫通知類
/*** 日志輸出通知類*/ public class LogAdvise {public void beforeLog(){System.out.println("方法開(kāi)始執(zhí)行!");}public void afterLog(){System.out.println("方法后置執(zhí)行!");}public void afterReturning(){System.out.println("方法返回了數(shù)據(jù)");}public void afterThrowing(){System.out.println("方法拋出了異常");}public void around(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("around方法名:" + joinPoint.getSignature().getName());System.out.println("around --前置");//原來(lái)方法joinPoint.proceed();System.out.println("around --后置");} }2.1.3 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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--配置包的掃描--><context:component-scan base-package="com.blb.aop_demo"></context:component-scan><!--配置通知類--><bean id="logAdvise" class="com.blb.aop_demo.util.LogAdvise"></bean><!--配置切面--><aop:config><!--配置切入點(diǎn)--><aop:pointcut id="pc" expression="execution(* com.blb.aop_demo.service.*Service.*(..))"/><!--配置切面 ref是通知類的bean--><aop:aspect id="aspect1" ref="logAdvise"><!--前置通知 method是對(duì)應(yīng)的通知方法 pointcut-ref是切入點(diǎn)--><aop:before method="beforeLog" pointcut-ref="pc"></aop:before><!--后置--><aop:after method="afterLog" pointcut-ref="pc"></aop:after><!--后置返回--><aop:after-returning method="afterReturning" pointcut-ref="pc"></aop:after-returning><!--后置拋異常--><aop:after-throwing method="afterThrowing" pointcut-ref="pc"></aop:after-throwing><!--環(huán)繞--><aop:around method="around" pointcut-ref="pc"></aop:around></aop:aspect></aop:config> </beans>2.1.4 測(cè)試
在com.blb.aop_demo.service包下添加幾個(gè)Service類做測(cè)試
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml"); GoodsService goodsService = context.getBean(GoodsService.class); goodsService.queryGoods(); goodsService.queryGoodsById(1); goodsService.createGoods(); goodsService.updateGoods(); goodsService.deleteGoodsById(1);2.1.5 配置詳解
aop:pointcut 是切入點(diǎn)配置
其中的核心是expression,通過(guò)表達(dá)式控制切面應(yīng)用的范圍
語(yǔ)法:
execution(訪問(wèn)修飾符 返回值 包名.類名.方法名(參數(shù)類型,參數(shù)類型....))通配符:
*代表任意長(zhǎng)度的字符.. 代替子包或任意參數(shù)3、AOP的注解配置
3.1 常用AOP相關(guān)注解
@Aspect 切面,配置到切面類上
@PointCut(“表達(dá)式”) 配置切入點(diǎn),加在方法上
@Before 配置前置通知方法
@After 配置后置通知方法
@Around 配置環(huán)繞通知方法
@AfterReturning 配置后置返回值通知方法
@AfterThrowing 配置后置拋出異常通知方法
3.2 AOP配置
1)配置類
@ComponentScan(basePackages = "com.blb.aop_demo") @Configuration //啟動(dòng)AspectJ的注解配置 @EnableAspectJAutoProxy public class AopConfig { }2) 日志切面
/*** 日志切面*/ @Aspect @Component public class LogAspect {//配置切入點(diǎn)@Pointcut("execution(* com.blb.aop_demo.service.*Service.*(..))")public void pointcut(){}//配置通知方法@Before("pointcut()")public void beforeLog(){System.out.println("這是前置的通知方法!!");} }3)測(cè)試
AnnotationConfigApplicationContext context2 = new AnnotationConfigApplicationContext(AopConfig.class); GoodsService goodsService = context2.getBean(GoodsService.class); goodsService.queryGoods(); goodsService.queryGoodsById(1); goodsService.createGoods(); goodsService.updateGoods(); goodsService.deleteGoodsById(1);4、日志跟蹤案例
4.1 案例概述
在實(shí)際項(xiàng)目部署上線后,都需要通過(guò)日志的搜集來(lái)定位出現(xiàn)的bug,日志跟蹤代碼如果在所有方法都寫,就會(huì)很繁瑣,代碼也不利于維護(hù),如果使用AOP就能很好解決這個(gè)問(wèn)題。
4.2 案例實(shí)現(xiàn)
log4j slf4j logback …
導(dǎo)入log4j依賴
添加log4j.properties
編寫日志切面
作業(yè)
1) 給寵物管理系統(tǒng)的service實(shí)現(xiàn)類加入日志跟蹤,輸出執(zhí)行方法名、參數(shù)、執(zhí)行事件、返回值 (Log4j) AOP
2) 在上面的基礎(chǔ)上,區(qū)分日志
? 1) 查詢方法
? 輸出方法名,返回的結(jié)果
? 2) 增刪改方法
? 輸出方法名,參數(shù),執(zhí)行時(shí)間
面試題:
1) 簡(jiǎn)介AOP
2) 介紹AOP的術(shù)語(yǔ)
3) 介紹AOP的XML配置方法
4) 介紹注解配置
總結(jié)
以上是生活随笔為你收集整理的快速入门Spring之SpringAOP的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [Spring入门学习笔记][Sprin
- 下一篇: Latex模版以及经验汇总