Spring_Spring与AOP_AspectJ基于注解的AOP实现

时间:2023-12-24 09:56:19

一、AspectJ、Spring与AOP的关系

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

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

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

二、AspectJ的通知类型

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

三、AspectJ的切入点表达式


Spring_Spring与AOP_AspectJ基于注解的AOP实现

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

Spring_Spring与AOP_AspectJ基于注解的AOP实现

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

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

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

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

三、AspectJ的开发环境


导入2个Jar包

spring-framework-3.0.2.RELEASE-dependencies\org.aspectj\com.springsource.org.aspectj.weaver\1.6.8.RELEASE

Spring_Spring与AOP_AspectJ基于注解的AOP实现

Spring_Spring与AOP_AspectJ基于注解的AOP实现

Spring_Spring与AOP_AspectJ基于注解的AOP实现

Spring_Spring与AOP_AspectJ基于注解的AOP实现

Spring_Spring与AOP_AspectJ基于注解的AOP实现

四、AspectJ基于注解的AOP实现

1、前置通知

 //主业务接口
public interface ISomeService {
//目标方法
void doFirst();
String doSecond();
void doThird(); }

ISomeService

 public class SomeServiceImpl implements ISomeService {

     @Override
public void doFirst() {
// TODO Auto-generated method stub
System.out.println("执行doFirst()方法");
} @Override
public String doSecond() {
// TODO Auto-generated method stub
System.out.println("执行doSecond()方法");
return "abcde";
} @Override
public void doThird() {
// TODO Auto-generated method stub
System.out.println("执行doThird()方法");
} }

SomeServiceImpl

 import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; @Aspect //表示当前类为切面
public class MyAspect {
@Before("execution(* *..ISomeService.doFirst(..))")
public void before(){
System.out.println("执行前置通知方法");
} @Before("execution(* *..ISomeService.doFirst(..))")
public void before(JoinPoint jp){
System.out.println("执行前置通知方法 jp="+jp);
} }

MyAspect

 import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { @Test
public void test01() {
//创建容器对象
String resource = "com/bjpowernode/annotation/applicationContext.xml";
ApplicationContext ac=new ClassPathXmlApplicationContext(resource); ISomeService service=(ISomeService) ac.getBean("someService");
service.doFirst();
System.out.println("--------------------");
service.doSecond();
System.out.println("--------------------");
service.doThird();
} }

MyTest

 <?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/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 注册切面 -->
<bean id="myAspect" class="com.bjpowernode.annotation.MyAspect"></bean> <!-- 注册目标对象 -->
<bean id="someService" class="com.bjpowernode.annotation.SomeServiceImpl"></bean> <!-- 注册AspectJ的自动代理 -->
<aop:aspectj-autoproxy/>
</beans>

ApplicationContext

输出:

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

output

2.后置通知

   @AfterReturning("execution(* *..ISomeService.doSecond(..))")
public void myAfterReturning(){
System.out.println("执行后置通知方法"); } @AfterReturning(value="execution(* *..ISomeService.doSecond(..))",returning="result")
public void myAfterReturning(Object result){
System.out.println("执行后置通知方法 result="+result); }

MyAspect

3、环绕通知

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

MyAspect

输出:

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

output

4、异常通知

  @AfterThrowing("execution(* *..ISomeService.doThird(..))")
public void myAfterThrowing(){
System.out.println("执行异常通知方法");
}

MyAspect

   @AfterThrowing(value="execution(* *..ISomeService.doThird(..))",throwing="ex")
public void myAfterThrowing(Exception ex){
System.out.println("执行异常通知方法ex="+ex.getMessage());
}

MyAspect

 执行异常通知方法ex=/ by zero

output

5、最终通知

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

五、定义切入点

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

  @After("doThirdPointcut()")
public void myAfter(){
System.out.println("执行最终通知方法");
}
//定义了一个切入点,叫doThirdPointcut()
@Pointcut("execution(* *..ISomeService.doThird(..))")
public void doThirdPointcut(){}
}