Spring AOP 面向切面编程 以注释方式配置

2019-07-29 0 By admin

一、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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       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 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd">
	<!--- 设置Spring 创建容器时要扫描的包-->
    <context:component-scan base-package="cn.gud"></context:component-scan>
	<!--- 开启Spring 对注释AOP 的支持  -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

二、AccountServiceImpl 实现类添加注释

@Service("accountService")

三、切面类

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

/*
 * 切面类:对目标对象进行日志部分的增强是通过此类中的方法来实现
 * 在切面类上:定义切面类
 * 在切面方法上:使用注解的形式定义通知类型
 */

@Component("logger")
@Aspect
public class Logger
{
/**
* 抽取切入点表达式
*    @Pointcut:定义切入点表达式
*    这个注解需要配置到方法上,这个方法是一个空的方法
*    应用这个切入点表达式的时候,只需要引入方法名就可以了。
*/
    @Pointcut(value="execution(* cn.gud.AccountSeriveImp.*(..))")
    public void pt() {}//定义一个通用的,这样前置通知,后置通知等等用的时候只需要引用这个方法名就行了
	
/*
* @Description //TODO 打印日志, 让其在切入点方法执行之前执行
* 定义前置通知
*  @Before :
*  value : 可以是一个切入点表达式,也可以是一个切入点表达式的引用
*/
    @Before("pt()")
    public void printLog(){
        System.out.println("Logger[printLog] is stating.....");
    }
}

四、通知类型

@Before
作用:把当前方法看成是前置通知。
属性:value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@AfterReturning
作用:把当前方法看成是后置通知。
属性:value:用于指定切入点表达式,还可以指定切入点表达式的引用
@AfterThrowing
作用:把当前方法看成是异常通知。
属性:value:用于指定切入点表达式,还可以指定切入点表达式的引用
@After
作用:把当前方法看成是最终通知。
属性:value:用于指定切入点表达式,还可以指定切入点表达式的引用
@Around
作用:把当前方法看成是环绕通知。
属性:value:用于指定切入点表达式,还可以指定切入点表达式的引用。
注意:
在使用除环绕通知的其他通知时,他们的顺序并不是一定的,最终通知会执行优先于后置通知与环绕通知,因此当我们使用最终通知来释放一些资源的时候,可能会出现资源已经释放,但是后置通知仍在使用的情况,这时就会出现错误,
我们遇到这种情况时要特别注意,为了保证通知的顺序,我们必要的使用环绕通知,环绕通知的执行顺序是一致的。