spring5入门(十三):Aspect注解使用、配置文件使用


  • 使用注解实现前置通知
# 创建普通类
public class User {

    public void add() {
        System.out.println("add.......");
    }

}

# 创建增强类
public class UserProxy {

 public void before() {//前置通知
   System.out.println("before......");
 }

}

# 开启注解扫描
<?xml version="1.0" encoding="UTF-8"?>

    
    


  • 使用注解创建对象
@Component
  • 增强类上面添加注解 @Aspect

  • 配置文件中开启生成代理对象


  • 增强类中使用切入点表达式
@Before(value = "execution(* com.ychen.spring.aopanno.User.add(..))")
  • 编写测试方法
    @Test
    public void testAopAnno() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        User user = context.getBean("user", User.class);
        user.add();
    }

# 测试
before.........
add.......
  • 完整代码
# 普通类
@Component
public class User {

    public void add() {
        System.out.println("add.......");
    }

}

# 增强类
@Component
@Aspect  //生成代理对象
public class UserProxy {

    //前置通知
    @Before(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void before() {
        System.out.println("before.........");
    }

    //后置通知(返回通知)
    @AfterReturning(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void afterReturning() {
        System.out.println("afterReturning.........");
    }

    //最终通知
    @After(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void after() {
        System.out.println("after.........");
    }

    //异常通知
    @AfterThrowing(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void afterThrowing() {
        System.out.println("afterThrowing.........");
    }

    //环绕通知
    @Around(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕之前.........");
        //被增强的方法执行
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后.........");
    }

}

# bean1.xml
<?xml version="1.0" encoding="UTF-8"?>

    
    

    
    


# 测试方法
    @Test
    public void testAopAnno() {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");
        User user = context.getBean("user", User.class);
        user.add();
    }

# 控制台
环绕之前.........
before.........
add.......
环绕之后.........
after.........
afterReturning.........
  • 异常通知没有执行,模拟一个异常
@Component
public class User {

    public void add() {
        // 模拟异常
        int i = 10/0;
        System.out.println("add.......");
    }

}

# 控制台
环绕之前.........
before.........
after.........
afterThrowing.........

java.lang.ArithmeticException: / by zero

	at com.atguigu.spring5.aopanno.User.add(User.java:11)
  • 重用切入点定义
# 普通类
@Component
public class User {

    public void add() {
        System.out.println("add.......");
    }

}

# 增强类
@Component
@Aspect  //生成代理对象
public class UserProxy {

    //相同切入点抽取
    @Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void pointdemo() {

    }

    //前置通知
    //@Before注解表示作为前置通知
    @Before(value = "pointdemo()")
    public void before() {
        System.out.println("before.........");
    }

    //后置通知(返回通知)
    @AfterReturning(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void afterReturning() {
        System.out.println("afterReturning.........");
    }

    //最终通知
    @After(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void after() {
        System.out.println("after.........");
    }

    //异常通知
    @AfterThrowing(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void afterThrowing() {
        System.out.println("afterThrowing.........");
    }

    //环绕通知
    @Around(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕之前.........");
        //被增强的方法执行
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后.........");
    }

}

# bean1.xml
<?xml version="1.0" encoding="UTF-8"?>

    
    

    
    


# 测试方法
    @Test
    public void testAopAnno() {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");
        User user = context.getBean("user", User.class);
        user.add();
    }

# 控制台
环绕之前.........
before.........
add.......
环绕之后.........
after.........
afterReturning.........
  • 有多个增强类对同一个普通类进行增强的时候,可以定义增强类的优先级
# 在增强类上面添加注解 @Order(数字类型值),数字类型值越小优先级越高
# 普通类
@Component
public class User {

    public void add() {
        System.out.println("add.......");
    }

}

# 增强类1
@Component
@Aspect  //生成代理对象
@Order(3)
public class UserProxy {

    //相同切入点抽取
    @Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void pointdemo() {

    }

    //前置通知
    //@Before注解表示作为前置通知
    @Before(value = "pointdemo()")
    public void before() {
        System.out.println("before.........");
    }

    //后置通知(返回通知)
    @AfterReturning(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void afterReturning() {
        System.out.println("afterReturning.........");
    }

    //最终通知
    @After(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void after() {
        System.out.println("after.........");
    }

    //异常通知
    @AfterThrowing(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void afterThrowing() {
        System.out.println("afterThrowing.........");
    }

    //环绕通知
    @Around(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕之前.........");
        //被增强的方法执行
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后.........");
    }

}

# 增强类2
@Component
@Aspect
@Order(1)
public class PersonProxy {

    //前置通知
    @Before(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void afterReturning() {
        System.out.println("Person Before.........");
    }

}

# bean1.xml
<?xml version="1.0" encoding="UTF-8"?>

    
    

    
    


# 测试方法
    @Test
    public void testAopAnno() {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");
        User user = context.getBean("user", User.class);
        user.add();
    }

# 控制台
Person Before.........
环绕之前.........
before.........
add.......
环绕之后.........
after.........
afterReturning.........

Process finished with exit code 0
  • xml配置方式进行通知
# 普通类
public class Book {
    
    public void buy() {
        System.out.println("buy.............");
    }
    
}

# 增强类
public class BookProxy {
    
    public void before() {
        System.out.println("before.........");
    }
    
}

# bean.xml配置
<?xml version="1.0" encoding="UTF-8"?>

    
    
    

    
    
        
        
        
        
            
            
        
    


# 测试方法
    @Test
    public void testAopXml() {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean2.xml");
        Book book = context.getBean("book", Book.class);
        book.buy();
    }

# 控制台
before.........
buy.............

Process finished with exit code 0
  • 纯注解开发方式
# 普通类
@Component
public class User {

    public void add() {
        // 模拟异常
        //int i = 10/0;
        System.out.println("add.......");
    }

}

# 增强类1
@Component
@Aspect  //生成代理对象
@Order(3)
public class UserProxy {

    //相同切入点抽取
    @Pointcut(value = "execution(* com.ychen.spring.aopanno.User.add(..))")
    public void pointdemo() {

    }

    //前置通知
    //@Before注解表示作为前置通知
    @Before(value = "pointdemo()")
    public void before() {
        System.out.println("before.........");
    }

    //后置通知(返回通知)
    @AfterReturning(value = "execution(* com.ychen.spring.aopanno.User.add(..))")
    public void afterReturning() {
        System.out.println("afterReturning.........");
    }

    //最终通知
    @After(value = "execution(* com.ychen.spring.aopanno.User.add(..))")
    public void after() {
        System.out.println("after.........");
    }

    //异常通知
    @AfterThrowing(value = "execution(* com.ychen.spring.aopanno.User.add(..))")
    public void afterThrowing() {
        System.out.println("afterThrowing.........");
    }

    //环绕通知
    @Around(value = "execution(* com.ychen.spring.aopanno.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕之前.........");
        //被增强的方法执行
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后.........");
    }

}

# 增强类2
@Component
@Aspect
@Order(1)
public class PersonProxy {

    //前置通知
    @Before(value = "execution(* com.ychen.spring.aopanno.User.add(..))")
    public void afterReturning() {
        System.out.println("Person Before.........");
    }

}

# 配置类
@Configuration
@ComponentScan(basePackages = {"com.ychen"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ConfigAop {
}

# 测试方法
public class Test1 {

    @Test
    public void testService2() {
        ApplicationContext context
                = new AnnotationConfigApplicationContext(ConfigAop.class);
        User user = context.getBean("user", User.class);
        user.add();
    }

}

# 控制台
Person Before.........
环绕之前.........
before.........
add.......
环绕之后.........
after.........
afterReturning.........

Process finished with exit code 0