aop有几种通知类型?

应用场景--对原有的程序进行扩展

  • 1,Before--前置通知

  • 2,After returning -- 返回通知

  • 3,After throwing -- 异常通知

  • 4,After -- 后置通知

  • 5,Around -- 环绕通知

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns="http://www.springframework.org/schema/beans"
       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">
    <!-- 定义类被Spring IOC容器管理 -->
    <bean class="top.xiongmingcai.spring.aop.SampleAspect" name="sampleAspect"/>
    <bean class="top.xiongmingcai.spring.aop.UserService" name="userService"/>
    <!-- 配置Spring AOP -->
    <aop:config>
        <!-- 配置过程中引用切面类 -->
        <aop:aspect ref="sampleAspect">
            <!-- PointCut(切点)-->
            <aop:pointcut id="samplePC" expression="execution(* top.xiongmingcai.spring.aop.*Service.create*(..))"/>
            <!--            <aop:after method="doBefore" pointcut-ref="samplePC"/>-->
            <!--            <aop:before pointcut-ref="samplePC" method="doBefore"/>-->
            <!--            <aop:after pointcut-ref="samplePC" method="doAfter"/>-->
            <!--            <aop:after-throwing method="doAfterThrowing" pointcut-ref="samplePC" throwing="t"/>-->
            <aop:around method="doAround" pointcut-ref="samplePC"/>
        </aop:aspect>
    </aop:config>
</beans>

or 注解模式

 <!--自动装配文件位置设置-->
    <context:component-scan base-package="com.ljs"/>
    <!--配置为自动代理-->
    <aop:aspectj-autoproxy/>

切面类

//切面类
public class SampleAspect {

    //1.前置通知
    public void doBefore(JoinPoint jp) {
        String clzName = jp.getTarget().getClass().getName();//getTarget() 获取即将要执行的对象
        String method = jp.getSignature().getName();//即将要执行的方法
        Object args = jp.getArgs();
        System.out.println("【前置通知】" + clzName + "." + method);
    }

    //2.后置通知
    public void doAfter(JoinPoint jp) {
        String clzName = jp.getTarget().getClass().getName();//getTarget() 获取即将要执行的对象
        String method = jp.getSignature().getName();//即将要执行的方法
        System.out.println("【后置通知】" + clzName + "." + method);

    }

    //3.返回通知
    public void doAfterReturning(JoinPoint jp, Object ret) {
        System.out.println("【返回后通知】" + ret);

    }

    //4.异常通知
    public void doAfterThrowing(JoinPoint jp, Throwable t) {
        System.out.println("【异常通知】" + t.getMessage());
    }

    //5.环绕通知
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        String clzName = pjp.getTarget().getClass().getName();//getTarget() 获取即将要执行的对象
        String method = pjp.getSignature().getName();//即将要执行的方法
        Object args = pjp.getArgs();
        System.out.println("【前置通知】" + clzName + "." + method);
        Object ret = null;
        try {
            ret = pjp.proceed();//执行目标方法
            System.out.println("【返回后通知】" + ret);
        } catch (Throwable t) {
            // TODO Auto-generated catch block
            System.out.println("【异常通知】" + t.getMessage());
            throw t;
        } finally {
            System.out.println("【后置通知】" + clzName + "." + method + "()");
        }
        return ret;
    }

}

or 注解模式

//BeanConfig.java
@ComponentScan("top.xiongmingcai.spring.aop")
@Configuration
@EnableAspectJAutoProxy
public class BeanConfig {

    @Bean("userService")
    public UserService userService() {
        UserService userService = new UserService();
        return userService;
    }

    @Bean
    public SampleAspect sampleAspect() {
        return new SampleAspect();
    }
}

//切面类
@Aspect
public class SampleAspect {
    @Pointcut("execution(public * top.xiongmingcai.spring.aop.*Service.create*(..))")
    public void pointcut() {
    }


    //1.前置通知
//    @Before("pointcut()")
    public void doBefore(JoinPoint jp) {
        String clzName = jp.getTarget().getClass().getName();//getTarget() 获取即将要执行的对象
        String method = jp.getSignature().getName();//即将要执行的方法
        Object args = jp.getArgs();
        System.out.println("【前置通知】" + clzName + "." + method);
    }

    //2.后置通知
//    @After("pointcut()")
    public void doAfter(JoinPoint jp) {
        String clzName = jp.getTarget().getClass().getName();//getTarget() 获取即将要执行的对象
        String method = jp.getSignature().getName();//即将要执行的方法
        System.out.println("【后置通知】" + clzName + "." + method);

    }

    //3.返回通知
//    @AfterReturning(value = "pointcut()", returning = "ret")
    public void doAfterReturning(JoinPoint jp, Object ret) {
        System.out.println("【返回后通知】" + ret);

    }

    //4.异常通知
//    @AfterThrowing(pointcut = "pointcut()", throwing = "t")
    public void doAfterThrowing(JoinPoint jp, Throwable t) {
        System.out.println("【异常通知】" + t.getMessage());
    }

    //5.环绕通知
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        String clzName = pjp.getTarget().getClass().getName();//getTarget() 获取即将要执行的对象
        String method = pjp.getSignature().getName();//即将要执行的方法
        Object args = pjp.getArgs();
        System.out.println("【前置通知】" + clzName + "." + method);
        Object ret = null;
        try {
            ret = pjp.proceed();//执行目标方法
            System.out.println("【返回后通知】" + ret);
        } catch (Throwable t) {
            // TODO Auto-generated catch block
            System.out.println("【异常通知】" + t.getMessage());
            throw t;
        } finally {
            System.out.println("【后置通知】" + clzName + "." + method + "()");
        }
        return ret;
    }

}

测试

public class AopApplication {
    public static void main(String[] args) {
//        ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:aop.xml");
        ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanConfig.class);
        UserService userService = (UserService) ctx.getBean("userService");
        userService.createUser();

    }
}

[MingCaiXiong/spring-bean-learn at java_config_@After注解方式配置_后置通知]](https://github.com/MingCaiXiong/spring-bean-learn/tree/java_config_%40After%E6%B3%A8%E8%A7%A3%E6%96%B9%E5%BC%8F%E9%85%8D%E7%BD%AE_%E5%90%8E%E7%BD%AE%E9%80%9A%E7%9F%A5%5D)