Spring_Spring与AOP_AspectJ基于注解的AOP实现

一、AspectJ、Spring与AOP的关系

AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。(百度百科)

Spring又将AspectJ的对于AOP的实现引入到自己的框架中。

在Spring中使用AOP开发时,一般使用AspectJ的实现方式。

二、AspectJ的通知类型

  1. 前置通知
  2. 后置通知
  3. 环绕通知
  4. 异常通知
  5. 最终通知

三、AspectJ的切入点表达式


表达式中加【】的部分表示可省略部分 ,个部分用空格分开。在其中可以使用以下符号:

execution(* * ..service.*.*(..))

指定所有包下的service子包下所有类(接口)中所有方法为切入点

execution(* *..ISomeService.*(..))

指定所有包下的ISomeService接口中所有方法为切入点

三、AspectJ的开发环境


导入2个Jar包

spring-framework-3.0.2.RELEASE-dependenciesorg.aspectjcom.springsource.org.aspectj.weaver1.6.8.RELEASE

四、AspectJ基于注解的AOP实现

1、前置通知

1 //主业务接口
2 public interface ISomeService {
3   //目标方法
4     void doFirst();
5     String doSecond();
6     void doThird();
7     
8 }
ISomeService
 1 public class SomeServiceImpl implements ISomeService {
 2 
 3     @Override
 4     public void doFirst() {
 5         // TODO Auto-generated method stub
 6         System.out.println("执行doFirst()方法");
 7     }
 8 
 9     @Override
10     public String doSecond() {
11         // TODO Auto-generated method stub
12         System.out.println("执行doSecond()方法");
13         return "abcde";
14     }
15 
16     @Override
17     public void doThird() {
18         // TODO Auto-generated method stub
19         System.out.println("执行doThird()方法");
20     }
21 
22 }
SomeServiceImpl
 1 import org.aspectj.lang.JoinPoint;
 2 import org.aspectj.lang.annotation.Aspect;
 3 import org.aspectj.lang.annotation.Before;
 4 
 5 @Aspect  //表示当前类为切面
 6 public class MyAspect {
 7    @Before("execution(* *..ISomeService.doFirst(..))")
 8    public void  before(){
 9        System.out.println("执行前置通知方法");
10    }
11    
12    @Before("execution(* *..ISomeService.doFirst(..))")
13    public void  before(JoinPoint jp){
14        System.out.println("执行前置通知方法 jp="+jp);
15    }
16     
17 }
MyAspect
 1 import org.junit.Test;
 2 import org.springframework.context.ApplicationContext;
 3 import org.springframework.context.support.ClassPathXmlApplicationContext;
 4 
 5 public class MyTest {
 6 
 7     @Test
 8     public void test01() {
 9         //创建容器对象
10         String resource = "com/bjpowernode/annotation/applicationContext.xml";
11         ApplicationContext ac=new ClassPathXmlApplicationContext(resource);
12        
13         ISomeService service=(ISomeService) ac.getBean("someService");
14         service.doFirst();
15         System.out.println("--------------------");
16         service.doSecond();
17         System.out.println("--------------------");
18         service.doThird();
19     }
20 
21 }
MyTest
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
 5         http://www.springframework.org/schema/beans 
 6         http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/aop 
 8         http://www.springframework.org/schema/aop/spring-aop.xsd">
 9     <!-- 注册切面 -->
10     <bean id="myAspect" class="com.bjpowernode.annotation.MyAspect"></bean>
11      
12      <!-- 注册目标对象 -->
13      <bean id="someService" class="com.bjpowernode.annotation.SomeServiceImpl"></bean>
14       
15      <!--   注册AspectJ的自动代理 -->
16      <aop:aspectj-autoproxy/>  
17 </beans>
ApplicationContext

输出:

执行前置通知方法
执行前置通知方法 jp=execution(void com.bjpowernode.annotation.ISomeService.doFirst())
执行doFirst()方法
--------------------
执行doSecond()方法
--------------------
执行doThird()方法
output

2.后置通知

 1   @AfterReturning("execution(* *..ISomeService.doSecond(..))")
 2    public void myAfterReturning(){
 3        System.out.println("执行后置通知方法");
 4        
 5    }
 6    
 7    @AfterReturning(value="execution(* *..ISomeService.doSecond(..))",returning="result")
 8    public void myAfterReturning(Object result){
 9        System.out.println("执行后置通知方法 result="+result);
10        
11    }
MyAspect

3、环绕通知

1    @Around("execution(* *..ISomeService.doSecond(..))")
2    public Object myAround(ProceedingJoinPoint pjp) throws Throwable{
3        System.out.println("执行环绕通知方法,目标方法执行之前");
4        //执行目标方法
5        Object result = pjp.proceed();
6        System.out.println("执行环绕通知方法,目标方法执行之后");
7     return result;
8        
9    }
MyAspect

输出:

1 执行环绕通知方法,目标方法执行之前
2 执行doSecond()方法
3 执行环绕通知方法,目标方法执行之后
output

4、异常通知

1  @AfterThrowing("execution(* *..ISomeService.doThird(..))")
2    public void myAfterThrowing(){
3       System.out.println("执行异常通知方法");  
4    }
MyAspect
1   @AfterThrowing(value="execution(* *..ISomeService.doThird(..))",throwing="ex")
2    public void myAfterThrowing(Exception ex){
3       System.out.println("执行异常通知方法ex="+ex.getMessage());  
4    }
MyAspect
1 执行异常通知方法ex=/ by zero
output

 5、最终通知

1  @After("execution(* *..ISomeService.doThird(..))")
2    public void myAfter(){
3       System.out.println("执行最终通知方法");  
4    }
View Code

五、定义切入点

定义了一个切入点,叫doThirdPointcut()

1  @After("doThirdPointcut()")
2    public void myAfter(){
3       System.out.println("执行最终通知方法");  
4    }
5    //定义了一个切入点,叫doThirdPointcut()
6    @Pointcut("execution(* *..ISomeService.doThird(..))")
7    public void doThirdPointcut(){}
8 }
原文地址:https://www.cnblogs.com/hoje/p/8471275.html