@AspectJ注解方式的aop


@AspectJ注解方式的aop

第一步:导入依赖
  <dependencies>
?
?
       
       <dependency>
           <groupId>org.springframeworkgroupId>
           <artifactId>spring-contextartifactId>
           <version>5.3.12version>
       dependency>
?
       
       <dependency>
           <groupId>org.springframeworkgroupId>
           <artifactId>spring-aspectsartifactId>
           <version>5.3.12version>
       dependency>
       
       <dependency>
           <groupId>org.slf4jgroupId>
           <artifactId>slf4j-log4j12artifactId>
           <version>1.7.25version>
       dependency>
       <dependency>
           <groupId>junitgroupId>
           <artifactId>junitartifactId>
           <version>4.12version>
           <scope>compilescope>
       dependency>
       
        <dependency>
           <groupId>org.springframeworkgroupId>
           <artifactId>spring-testartifactId>
           <version>5.3.7version>
           <scope>testscope>
       dependency>
   dependencies>
?
第二步:开启@aspect注册 和包扫描
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns="http://www.springframework.org/schema/beans"
      xmlns:aop="http://www.springframework.org/schema/aop"
      xmlns:context="http://www.springframework.org/schema/context"
      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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
?
?
   
   <context:component-scan base-package="com.bird"/>
?
   
   <aop:aspectj-autoproxy/>
?
beans>
第三步:定义目标对象并注入到spring容器中
public interface ICustomerService {
   public void save();
   public int find();
   public  int error();
}
@Component
public class ICustomerServiceImpl implements ICustomerService {
   public void save() {
       System.out.println("客户保存了。。。。。");
  }
?
   public int find() {
       System.out.println("客户查询数量了。。。。。");
       return 100;
  }
?
   @Override
   public int error() {
       int a = 1 / 0;
       return 0;
  }
}
=======上面是基于接口的动态代理========下面是基于类的动态代理=========
@Service
public class ProductService {
   public void save() {
       System.out.println("商品保存了。。。。。");
  }
?
   public int find() {
       System.out.println("商品查询数量了。。。。。");
       return 99;
  }
}
?
第四步:编写通知类 并注入到spring容器中
package com.bird.advice.annotationaspectjaop.aspect;
?
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
?
/**
* @data 2021/11/28 10:03
* @author: bird
* @description: 这个是基于注解的方式定义的通知类
*/
@Component(value = "myAspect") // 将当前类注入到spring容器中
@Aspect //将该类标识为切面类(这里面有方法进行增强),相当于 //声明但前的这个类是通知类 专门用来增强
public class MyAspect {
?
   // 这个是基于接口的
   // 切入点:切入点就是拦截方法 意思就是要对哪些方法进行拦截 然后在通知里面进行拦截
   @Pointcut(value = "execution(* com.bird.advice.annotationaspectjaop.targetobject.ICustomerServiceImpl.save(..))")
   public void myPointcut() {
  }
?
   // 这个是基于类 进行切入点的
   @Pointcut(value = "execution(* com.bird.advice.annotationaspectjaop.targetobject.ProductService.save(..))")
   public void mypointcut2() {
  }
?
   @Pointcut(value = "execution(* com.bird.advice.annotationaspectjaop.targetobject.ProductService.find(..))")
   public void myPointcut3() {
  }
?
   @Pointcut(value = "execution(* com.bird.advice.annotationaspectjaop.targetobject.ICustomerServiceImpl.find(..))")
   public void myPointcut4() {
  }
?
   @Pointcut(value = "execution(* com.bird.advice.annotationaspectjaop.targetobject.ICustomerServiceImpl.error(..))")
   public void myPointcut5() {
?
  }
?
?
   // 前置通知 在save方法执行之前 执行的方法
   @Before(value = "myPointcut()|| mypointcut2()")
   public void before(JoinPoint joinPoint) {
       System.out.println("=======前置通知。。。。。");
  }
?
?
   // 后置通知
   @AfterReturning(value = "myPointcut()|| mypointcut2()||myPointcut3()", returning = "returnVal")
   public Object afterReturning(JoinPoint joinPoint, Object returnVal) {
       System.out.println("++++++++后置通知+++++++++++++:结果" + returnVal);
       return returnVal;
  }
?
?
   // 环绕通知
   @Around(value = "myPointcut4()")
   public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
       System.out.println("环绕通知------前");
       Object proceed = proceedingJoinPoint.proceed();
       System.out.println("环绕通知------后");
       return proceed;
  }
?
   // 抛出通知 若目标方法执行时 抛出了异常 那么就会执行这个增强
   @AfterThrowing(value = "myPointcut5()", throwing = "ex")
   public void afterThrowing(JoinPoint joinPoint, Throwable ex) {
       StackTraceElement[] stackTrace = ex.getStackTrace();
       StackTraceElement stackTraceElement = stackTrace[0];
       System.out.println("---抛出通知......------抛出的信息:" + ex.getMessage() + "具体的错误行:" + stackTraceElement);
  }
?
   // 最终通知 无论目标方法是否发生了异常都会执行下面的方法
   @After(value = "myPointcut5()")
   public void after(JoinPoint joinPoint) {
       System.out.println("--最终通知-----不管是否发生了异常----");
  }
?
}
?
第五步:测试
package com.bird.jdkproxy;
?
import com.bird.advice.annotationaspectjaop.targetobject.ICustomerService;
import com.bird.advice.annotationaspectjaop.targetobject.ProductService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
?
/**
* @data 2021/11/28 10:21
* @author: bird
* @description: 这个是基于注解的方式实现的aop
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext-annotation-aspect.xml") // 加载指定位置的bean
public class SpringAspectTest {
?
?
   @Autowired
   private ICustomerService customerService;
?
?
   @Autowired
   private ProductService productService;
?
   @Test
   public void test() {
       // 基于接口
       customerService.save();
       customerService.find();
       System.out.println("******************************************************");
       // 基于类
       productService.find();
       productService.save();
?
       System.out.println("%%%%%%%%%%%%%下面是抛出异常通知%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
       customerService.error();
?
  }
}
?