30&31、Spring5之AOP操作-AspectJ注解

106 阅读2分钟

AOP操作(AspectJ注解)

1、创建类,在类里面定义方法

package com.atguigu.spring5.aopanno;
// 被增强的类
public class User {
    public void add() {
        System.out.println("add....");
    }
}

2、创建增强类(编写增强的逻辑)

  • (1) 在增强类里面,创建方法,让不同方法代表不同通知类型
package com.atguigu.spring5.aopanno;
// 增强的类
public class UserProxy {
    // 前置通知
    public void before() {
        System.out.println("before...");
    }
}

3、进行通知的配置

  • (1)在spring配置文件中,开始注解扫描
<?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:context="http://www.springframework.org/schema/context"
       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/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

<!--  开启注解扫描  -->
    <context:component-scan base-package="com.atguigu.spring5.aopanno"></context:component-scan>
</beans>
  • (2)使用注解创建User和UserProxy对象
package com.atguigu.spring5.aopanno;
import org.springframework.stereotype.Component;
// 被增强的类
@Component  // 使用注解创建User对象
public class User {
    public void add() {
        System.out.println("add....");
    }
}
package com.atguigu.spring5.aopanno;
import org.springframework.stereotype.Component;
// 增强的类
@Component // 使用注解创建UserProxy对象
public class UserProxy {
    // 前置通知
    public void before() {
        System.out.println("before...");
    }
}
  • (3)在增强类上面添加注解@Aspect
package com.atguigu.spring5.aopanno;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
// 增强的类
@Component
@Aspect // 生成代理对象
public class UserProxy {
    // 前置通知
    public void before() {
        System.out.println("before...");
    }
}

  • (4)在spring配置文件中开启生成代理对象
<?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:context="http://www.springframework.org/schema/context"
       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/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

<!--  开启注解扫描  -->
    <context:component-scan base-package="com.atguigu.spring5.aopanno"></context:component-scan>
<!--  开启 Aspectj 生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

4、配置不同类型的通知

  • (1)在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
package com.atguigu.spring5.aopanno;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

// 增强的类
@Component
@Aspect // 生成代理对象
public class UserProxy {
    // 前置通知
    // @Before注解表示作为前置通知
    @Before(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))") // 调用相同切入点公共方法
    public void before() {
        System.out.println("before...");
    }
    //  最终通知
    @After(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void after() {
        System.out.println("after...");
    }
    // 后置通知(返回通知)
    @AfterReturning(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void afterReturning() {
        System.out.println("afterReturning...");
    }
    // 异常通知
    @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("环绕之后...");
    }
}

5、相同切入点抽取

package com.atguigu.spring5.aopanno;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
// 增强的类
@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...");
    }
}

6、有多个增强类多个同一个方法进行增强,设置类优先级

package com.atguigu.spring5.aopanno;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Aspect
@Order(1) // 数值越小,优先级越高
public class PersonProxy {
    // 相同切入点抽取
    @Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void pointdemo() {

    }
    // 前置通知
    // @Before注解表示作为前置通知
    @Before(value = "pointdemo()") // 调用相同切入点公共方法
    public void before() {
        System.out.println("PersonProxy before...");
    }
}

package com.atguigu.spring5.aopanno;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

// 增强的类
@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...");
    }
}

7、完全使用注解开发

  • (1)创建配置类,不需要创建xml配置文件
package com.atguigu.spring5.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan(basePackages = {"com.atguigu"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ConfigAop {
}
  • 测试代码test