Spring AOP之@Aspect

一、AOP底层原理实现

  1. 假如目标对象(被代理对象)实现接口,则底层默认采用JDK动态代理机制为目标对象创建代理对象(目标类和代理类会实现共同接口)
  2. 假如目标对象(被代理对象)没有实现接口,则底层默认采用CGLIB代理机制为目标对象创建代理对象(默认创建的代理类会继承目标对象类型)

二、maven 项目添加依赖

<dependency>
	<groupId>org.aspectj</groupId>
	    <artifactId>aspectjrt</artifactId>
		<version>1.8.9</version>
</dependency>

<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.8.9</version>
</dependency>

三、配置AOP实现

spring配置:

<!-- 启用AOP注解(自动为目标对象创建代理对象) -->
<aop:aspectj-autoproxy/>

配置类上使用@EnableAspectJAutoProxy

 

四、类型通知(Advice)

在AOP编程中有五种类型的通知:

  1. 前置通知 (@Before) 方法执行之前执行
  2. 返回通知 (@AfterReturning) 方法return之后执行
  3. 异常通知 (@AfterThrowing) 方法出现异常之后执行
  4. 后置通知 (@After) : 又称为最终通知(finally)
  5. 环绕通知 (@Around) :以上四个一起使用时可以直接使用@Around通知替换

结构如下:

Try{

   @Before

   核心业务

   @AfterReturning

}catch(Exception e){

   ….

   @AfterThrowing

}finally{

   ….

   @After

}

 

 

五、切面表达式

指示符

作用

bean

用于匹配指定bean id的的方法执行

within

          

用于匹配指定包名下类型内的方法执行

@annotation

用于匹配指定注解修饰的方法执行

execution

用于进行细粒度方法匹配执行具体业务

bean应用于类级别,实现粗粒度的控制:

 

bean(userServiceImpl)

指定一个类

bean(*ServiceImpl)

指定所有的后缀为serviceImpl的类

within应用于类级别,实现粗粒度的控制:

 

within(aop.service.UserServiceImpl)

指定类,只能指定一个类

within(aop.service.*)

只包括当前目录下的类

within(aop.service..*)

指定当前目录包含所有子目录中的类

execution方法级别,实现细粒度的控制:

语法:execution(返回值类型 包名.类名.方法名(参数列表))

execution(void aop.UserServiceImpl.addUser())

匹配方法

execution(void aop.UserServiceImpl.addUser(String))

方法参数必须为字符串

execution(* aop..*.*(..))

万能配置

@annotaion应用于方法级别,实现细粒度的控制:

@annotation(com.anno.CheckLog)

指定注解全路径,在需要应用的的方法上加上注解@CheckLog

六、多个切面作用于同一方法

可在切面上加上@Order(1) @Order(2) @Order(n)...优先执行@Order(1)的切面
 

七、实例说明

@Order(1)
@Aspect
@Service
public class TestAspect {
	 @Pointcut("bean(UserServiceImpl)")
//	 @Pointcut("within(com.*)")
//	 @Pointcut("execution(* com..*.*(..))")
//	 @Pointcut("@annotation(com.anno.CheckLog)")
	 public void doAspect() {}
    
	 @Before("doAspect()")
	 public void before() {
		 System.out.println("@Before");
	 }

     @After("doAspect()")
     public void after() {
    	 System.out.println("@After");
     }

     @AfterReturning("doAspect()")
     public void afterReturning() {
    	 System.out.println("@AfterReturning");
     }

     @AfterThrowing("doAspect()")
     public void afterThrowing() {
    	 System.out.println("@AfterThrowing");
     }

     @Around("doAspect()")
     public Object around(ProceedingJoinPoint joinPoint)
    		 throws Throwable{
		 try{
			 System.out.println("@Around before");
			 Object result = joinPoint.proceed();
			 System.out.println("@AfterReturning");
			 return result;
		 }catch(Exception e){
			 System.out.println("@AfterThrowing");
			 throw e;
		 }finally{
			 System.out.println("@After");
		 }
     }
}
发布了29 篇原创文章 · 获赞 8 · 访问量 7020

猜你喜欢

转载自blog.csdn.net/weixin_42032199/article/details/98521802