15.Aop--实现

zhanglei 2022年05月31日 273次浏览

具体步骤

/*
* 1.先创建一个User类
* 2.再创建一个UserProxy类:
*   在增强类里面,创建方法,让不同的方法代表不同的通知(增强)
* 3.进行通知的配置
*   在Spring配置文件中,开启注解扫描
*   使用注解创建User和UserProxy对象
*   在增强类上面添加注解@Aspect
*   在Spring配置文件中开启 生成代理对象
* 4.配置不同类型的通知
*   在增强类的里面,在作为通知(增强)方法上添加通知类型注解,使用切入点表达式配置
* */

用到的注解

1.@Aspect

该注解放在类的上面,加了该注解的类表示将该类设为切面,表明要在该类中存放通知

2.@Before

参数是切入点表达式:“execution(* 全限定路径.原方法名(…))”

该注解放在方法上,表明该方法要作为原方法(切入点)的前置通知

3.@After

参数是切入点表达式:“execution(* 全限定路径.原方法名(…))”

该注解放在方法上,表明该方法要作为原方法(切入点)的最终通知

不管切入点方法是否出现异常,后置通知都执行!

4.@AfterReturning

参数是切入点表达式:“execution(* 全限定路径.原方法名(…))”

该注解放在方法上,表明该方法要作为原方法(切入点)的后置通知

如果切入点方法出现异常,后置通知不执行!

5.@Around

参数是切入点表达式:“execution(* 全限定路径.原方法名(…))”

该注解放在方法上,表明该方法要作为原方法(切入点)的环绕通知

既是环绕,所以有“两个通知”

具体实现

被增强的类

package package1;

//被增强的类

import org.springframework.stereotype.Component;

@Component
public class User {
    public void add(){
        System.out.println("add...");
    }
}

存放通知的类

package package1;

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

@Component
@Aspect//存在增强的类称为切面--@Aspect将当前面设为切面,供容器读取
public class UserProxy {
    //前置通知
    //execution(...)为切入点表达式,表明哪个方法被增强
    @Before("execution(* package1.User.add(..))")//表示作为前置通知:在增强方法的前面执行
    public  void before(){
        System.out.println("before...");
    }
    //最终通知:不管被增强的方法(这里是add)是否出现异常,都执行
    @After("execution(* package1.User.add(..))")
    public  void after(){
        System.out.println("after...");
    }
    //后置(返回)通知:如果被增强的方法(这里是add)出现异常,不执行
    @AfterReturning("execution(* package1.User.add(..))")
    public  void afterReturning() {
        System.out.println("afterReturning...");
    }
    //环绕通知
    @Around("execution(* package1.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"?>
<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="package1"></context:component-scan>
<!--开启Aspect生成代理对象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

Test类

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

测试结果

环绕之前
before...
add...
afterReturning...
after...
环绕之后