基于使用AspectJ实现AOP,注解AOP开发(基于xml文件、基于注解)
AOP概念
AOP是Aspect Oriented Programming的縮寫,即『面向切面編程』。它和我們平時接觸到的OOP都是編程的不同思想,OOP,即『面向對象編程』,它提倡的是將功能模塊化,對象化,而AOP的思想,則不太一樣,它提倡的是針對同一類問題的統一處理,當然,我們在實際編程過程中,不可能單純的安裝AOP或者OOP的思想來編程,很多時候,可能會混合多種編程思想,大家也不必要糾結該使用哪種思想,取百家之長,才是正道
AspectJ
AspectJ實際上是對AOP編程思想的一個實踐,當然,除了AspectJ以外,還有很多其它的AOP實現,例如ASMDex,但目前最好、最方便的,依然是AspectJ。
Advice(通知)
注入到class文件中的代碼。典型的 Advice 類型有 before、after 和 around,分別表示在目標方法執行之前、執行后和完全替代目標方法執行的代碼。 除了在方法中注入代碼,也可能會對代碼做其他修改,比如在一個class中增加字段或者接口。
Joint point(連接點)
程序中可能作為代碼注入目標的特定的點,例如一個方法調用或者方法入口。
Pointcut(切入點)
告訴代碼注入工具,在何處注入一段特定代碼的表達式。例如,在哪些 joint points 應用一個特定的 Advice。切入點可以選擇唯一一個,比如執行某一個方法,也可以有多個選擇,比如,標記了一個定義成@DebguTrace 的自定義注解的所有方法。
AspectJ提供不同類型的通知,分別為:
@Before 前置通知,相當于BeforeAdvice
@AfterReturning 后置通知,相當于AfterReturningAdvice
@Around 環繞通知,相當于MethodInterceptor
@AfterThrowing異常拋出通知,相當于ThrowAdvice
@After 最終final通知,不管是否異常,該通知都會執行
1:引入aspectj依賴
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.6</version></dependency>?
2:新建一個User類
?
public class User {public void add(){System.out.println("add方法");} }?
3:新建一個UserProxy類,被增強的一個類,
Before方法上加上@Before注解,配置切入點表達式, *表示所有修飾符類型,后面加一個空格接著后面上全路徑和方法名,最后..表示參數
@Component @Aspect //表示生成一個代理對象 public class UserProxy {//前置通知//@Before注解表示作為前置通知@Before("execution(* com.example.wzy.demo.aop.User.add(..))")public void before(){System.out.println("before方法");} }?
?
4:新建一個bean9.xml
首先加上context和aop的名稱空間
接著配置開啟組件掃描
<context:component-scan base-package="com.example.wzy.demo.aop"></context:component-scan>com.example.wzy.demo.aop是全路徑,表示掃描這個包
?
還有添加
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>表示開啟Aspect生成代理對象,就是去類上找有沒有@Aspect注解,有的話就把這個對象生成一個代理對象
?
5:最后添加一個測試類
?
6:輸出結果,這就是前置通知,在方法執行之前執行
?
?
?
?
@Component @Aspect //表示生成一個代理對象 public class UserProxy {//前置通知//@Before注解表示作為前置通知@Before("execution(* com.example.wzy.demo.aop.User.add(..))")public void before() {System.out.println("before方法");}//后置通知,最終通知,方法執行之后執行,有異常也會執行@After("execution(* com.example.wzy.demo.aop.User.add(..))")public void after() {System.out.println("after方法");}//后置通知(返回通知)方法返回結果之后執行,有異常不執行@AfterReturning("execution(* com.example.wzy.demo.aop.User.add(..))")public void afterReturning() {System.out.println("AfterReturning");}//異常通知@AfterThrowing("execution(* com.example.wzy.demo.aop.User.add(..))")public void afterThrowing() {System.out.println("AfterThrowing");}//環繞通知@Around("execution(* com.example.wzy.demo.aop.User.add(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("環繞通知之前");proceedingJoinPoint.proceed();//被增強的方法執行System.out.println("環繞通知之后");} }?
?
?
?
優化:
相同的切入點抽取,下面的都是重復的,可以提取出來,如下圖
execution(* com.example.wzy.demo.aop.User.add(..))?
?
比如對User的add方法需要兩個增強類,那么使用
@Order()注解可以,里面的數字越小表示先執行?
看下執行結果
?
?
?
?
?
使用下xml配置文件配置
新建Book類和BookProxy類
public class Book {public void buy(){System.out.println("buy*********");} } public class BookProxy {public void before(){System.out.println("before**********");} }?
2:新建bean.xml
<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--名稱空間--><!--創建對象--><bean id="book" class="com.example.wzy.demo.aopxml.Book"></bean><bean id="bookProxy" class="com.example.wzy.demo.aopxml.BookProxy"></bean><!--配置aop增強--><aop:config><!--切入點--><aop:pointcut id="p" expression="execution(* com.example.wzy.demo.aopxml.Book.buy(..))"/><!--配置切面--><aop:aspect ref="bookProxy"><!--增強作用在具體的方法上--><aop:before method="before" pointcut-ref="p"/></aop:aspect></aop:config> </beans>?
新建測試類
?
@Testpublic void test2(){ApplicationContext ac = new ClassPathXmlApplicationContext("bean10.xml");Book book = ac.getBean("book", Book.class);book.buy();}執行結果
配置的是前置通知,所以先輸出before再輸出buy
?
?
總結
以上是生活随笔為你收集整理的基于使用AspectJ实现AOP,注解AOP开发(基于xml文件、基于注解)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Golang 垃圾回收机制
- 下一篇: 《计算机网络微课堂》一、计算机网络概述(