AspectJ对AOP的实现
引言
1.對于AOP編程思想,很多框架都進行了實現,Spring就是其中之一,可以完成面向切面編程。然后,AspectJ也實現了AOP的功能。并且實現的更加簡單、方便,并且還支持注解式開發。所以,spring又將AspectJ的對于AOP的實現也引入到了自己的框架中。
2.在Spring中使用AOP開發的時候,一般使用AspectJ的實現方式。
3.AspectJ是一個優秀的面向切面的框架,它擴展了java語言,提供了強大的切面實現,它是Eclipse的一個開源項目。
2.AspectJ的通知類型
AspectJ中常用的通知有五種類型:
1.前置通知@Before
2.后置通知@AfterReturning
3.環繞通知@Arround
4.異常通知@After Throwing
5.最終通知@After
3.AspectJ的切入點表達式
3.準備AspectJ的開發環境
1.加入Maven依賴
```xml<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.bjpowernode</groupId><artifactId>ch06-aop-aspectj</artifactId><version>1.0-SNAPSHOT</version><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><!--spring依賴--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.5.RELEASE</version></dependency><!--aspectj依賴--><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.2.5.RELEASE</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.1</version></dependency></dependencies><build><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build> </project>2.引入AspectJ依賴
4.AspectJ基于注解的AOP實現
實現步驟
a.定義業務接口和實現類
b.定義切面類
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before;import java.util.Date;/*** @Aspect : 是aspectj框架中的注解。* 作用:表示當前類是切面類。* 切面類:是用來給業務方法增加功能的類,在這個類中有切面的功能代碼* 位置:在類定義的上面*/ @Aspect public class MyAspect {/*** 定義方法,方法是實現切面功能的。* 方法的定義要求:* 1.公共方法 public* 2.方法沒有返回值* 3.方法名稱自定義* 4.方法可以有參數,也可以沒有參數。* 如果有參數,參數不是自定義的,有幾個特殊參數類型可以使用。*//*** @Before: 前置通知注解* 屬性:value ,是切入點表達式,表示切面的功能執行的位置。* 位置:在方法的上面* 特點:* 1.在目標方法之前先執行的* 2.不會改變目標方法的執行結果* 3.不會影響目標方法的執行。*/@Before(value = "" +"execution(" +"public void com.bjpowernode.ba01.SomeServiceImpl.doSome(String,Integer))" +"")public void myBefore(){//就是你目標類要增加的功能代碼System.out.println("前置通知, 切面功能:在目標方法之前輸出執行時間:"+ new Date());}/*@Before(value = "execution(void com.bjpowernode.ba01.SomeServiceImpl.doSome(String,Integer))")public void myBefore(){//就是你切面要執行的功能代碼System.out.println("1=====前置通知, 切面功能:在目標方法之前輸出執行時間:"+ new Date());}*//* @Before(value = "execution(void *..SomeServiceImpl.doSome(String,Integer))")public void myBefore(){//就是你切面要執行的功能代碼System.out.println("2=====前置通知, 切面功能:在目標方法之前輸出執行時間:"+ new Date());}*//*@Before(value = "execution(* *..SomeServiceImpl.*(..))")public void myBefore(){//就是你切面要執行的功能代碼System.out.println("3=====前置通知, 切面功能:在目標方法之前輸出執行時間:"+ new Date());}*//*@Before(value = "execution(* do*(..))")public void myBefore2(){//就是你切面要執行的功能代碼System.out.println("4=====前置通知, 切面功能:在目標方法之前輸出執行時間:"+ new Date());}*//*@Before(value = "execution(* com.bjpowernode.ba01.*ServiceImpl.*(..))")public void myBefore2(){//就是你切面要執行的功能代碼System.out.println("2=====前置通知, 切面功能:在目標方法之前輸出執行時間:"+ new Date());}*//*** 指定通知方法中的參數 : JoinPoint* JoinPoint:業務方法,要加入切面功能的業務方法* 作用是:可以在通知方法中獲取方法執行時的信息, 例如方法名稱,方法的實參。* 如果你的切面功能中需要用到方法的信息,就加入JoinPoint.* 這個JoinPoint參數的值是由框架賦予, 必須是第一個位置的參數*/@Before(value = "execution(void *..SomeServiceImpl.doSome(String,Integer))")public void myBefore(JoinPoint jp){ //下面就是切面要執行的功能//獲取方法的完整定義System.out.println("方法的簽名(定義)="+jp.getSignature());System.out.println("方法的名稱="+jp.getSignature().getName());//獲取方法的實參Object args [] = jp.getArgs();for (Object arg:args){System.out.println("參數="+arg);}//就是你切面要執行的功能代碼System.out.println("2=====前置通知, 切面功能:在目標方法之前輸出執行時間:"+ new Date());} }c. 聲明目標對和目標類對象
<?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: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/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--把對象交給spring容器,由spring容器統一創建,管理對象--><!--聲明目標對象--><bean id="someService" class="com.bjpowernode.ba01.SomeServiceImpl" /><!--聲明切面類對象--><bean id="myAspect" class="com.bjpowernode.ba01.MyAspect" /><!--聲明自動代理生成器:使用aspectj框架內部的功能,創建目標對象的代理對象。創建代理對象是在內存中實現的, 修改目標對象的內存中的結構。 創建為代理對象所以目標對象就是被修改后的代理對象.aspectj-autoproxy:會把spring容器中的所有的目標對象,一次性都生成代理對象。--><aop:aspectj-autoproxy /><!--有接口也想用cjlib實現動態代理:如果你期望目標類有接口,使用cglib代理proxy-target-class="true":告訴框架,要使用cglib動態代理--> <!-- <aop:aspectj-autoproxy proxy-target-class="true"/>--> </beans>d.測試類中使用目標對象的id(測試前置通知@Before)
import com.bjpowernode.ba01.SomeService; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest01 {@Testpublic void test01(){String config="applicationContext.xml";ApplicationContext ctx = new ClassPathXmlApplicationContext(config);//從容器中獲取目標對象SomeService proxy = (SomeService) ctx.getBean("someService");//com.sun.proxy.$Proxy8 :jdk動態代理//com.sun.proxy.$Proxy0System.out.println("proxy:"+proxy.getClass().getName());//通過代理的對象執行方法,實現目標方法執行時,增強了功能proxy.doSome("lisi",20);} }5.@Before前置通知-參數JoinPoint
6.@AfterReturning后置通知-returning屬性
7.@Around環繞通知- ProceedingJoinPoint 參數
8.AfterThrowing異常通知-throwing屬性
9.@After最終通知
10.@Pointcut定義切入點
總結
以上是生活随笔為你收集整理的AspectJ对AOP的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 配置tomcat的环境变量
- 下一篇: Spring Ioc注解式开发中注解的作