Spring:AOP(四)注解方式实现AOP

来源:互联网 发布:mysql 复合主键怎么写 编辑:程序博客网 时间:2024/05/22 17:49

配置文件中

<?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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">



    <!-- 配置Service对象-->
    <bean id="userService" class="cn.itcast.spring.o_aop_annotation.UserServiceImpl"></bean>

    <!-- 配置通知对象 -->
    <bean class="cn.itcast.spring.o_aop_annotation.LogAdvice"></bean>

    <!-- 使用基于注解的方式配置切面,需要有下面这个配置 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>


//切面

@Aspect
public class LogAdvice {

    // 声明一个切入点。本方法不能有返回值与参数
    @Pointcut("execution(* *(..))")
    private void myPointcut() {
    }

    // 前置通知,在原方法执行之前
    @Before("myPointcut()")
    public void before() {
        System.out.println("== before ==");
    }

    // 最终通知,在原方法执行之后
    // 如果原方法有异常,也会执行
    @After("myPointcut()")
    public void after() {
        System.out.println("== after ==");
    }

    // 后置通知,在原方法执行之后
    // 如果原方法有异常,则不执行。
    // 方法一:@AfterReturning("myPointcut()")
    // 方法二:@AfterReturning(pointcut = "myPointcut()")
    // 可以使用returning参数指定返回值的对应的参数名,Spring就会在调用本方法时把返回值传给指定名称的参数
    @AfterReturning(pointcut = "myPointcut()", returning = "returnValue")
    public void afterReturning(Object returnValue) {
        System.out.println(returnValue);
        System.out.println("== afterReturning ==");
    }

    // 异常通知,在出现异常之后
    // @AfterThrowing("myPointcut()")
    @AfterThrowing(pointcut = "myPointcut()", throwing = "ex")
    public void afterThrowing(Exception ex) {
        System.out.println(ex);
        System.out.println("== afterThrowing ==");
    }

    // 环绕通知,在原方法调用的前后执行。
    // 在原方法执行出异常后,环绕通知的后面部分不会执行。
    // 一定要在执行完原方法后,从本方法中返回结果。
    @Around("myPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("== 环绕通知(前) ==");
        Object result = joinPoint.proceed(); // 执行原方法
        System.out.println("== 环绕通知(后) ==");

        return result;
    }
}


@Test
    public void testUserService() throws Exception {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml", getClass());
        UserService userService = (UserService) ac.getBean("userService");

        // ===================================================
        // 使用的是代理对象

        userService.saveUser();
        System.out.println();

        userService.queryUsers();
        System.out.println();

        userService.deleteUser();
        System.out.println();
    }


通知的执行顺序

前置通知    before
后置通知    afterReturning
异常通知    afterThrowing
最终通知    after
环绕通知(前、后)around
ProceedingJoinPoint

以上所有通知都配置上时,执行结果如下:
1,不抛异常:
    == before ==
    == 环绕通知(前) ==
    >> 删除一个User <<
    == after ==
    == afterReturning ==
    == 环绕通知(后) ==
2,抛异常    
    == before ==
    == 环绕通知(前) ==
    >> 查询所有User <<
    == after ==
    == afterThrows ==


0 0
原创粉丝点击