Spring基础——AOP通知

spring(AOP)

切面

切面是封装通用业务逻辑的组件,可以作用到其他组件上。是spring组件中的某个方法、无返回类型、参数类型与通知类型有关。
一个切面 开启数据库 关闭数据库 开启事务 检查登录账号状态 监测账号权限

切点

用于指定哪些组件哪方法使用切面组件,Spring提供表达式来实现该制定。

通知

用于指定组件作用到目标组件的具体位置。

连接点(Joinpoint)
  增强程序执行的某个特定位置(要在哪个地方做增强操作)。Spring仅支持方法的连接点,既仅能在方法调用前,方法调用后,方法抛出异常时等这些程序执行点进行织入增强。

切点(Pointcut)
  切点是一组连接点的集合。AOP通过“切点”定位特定的连接点。通过数据库查询的概念来理解切点和连接点的关系再适合不过了:连接点相当于数据库中的记录,而切点相当于查询条件。

增强(Advice)
  增强是织入到目标类连接点上的一段程序代码。表示要在连接点上做的操作。

切面(Aspect)
  切面由切点和增强(引介)组成(可以包含多个切点和多个增强),它既包括了横切逻辑的定义,也包括了连接点的定义,SpringAOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的链接点中。

注解使用

@aspect 定义切面
@pointcut 定义切点
@before 标注Before Advice定义所在的方法
@afterreturning 标注After Returning Advice定义所在的方法
@afterthrowing 标注After Throwing Advice定义所在的方法
@after 标注 After(Finally) Advice定义所在的方法
@around 标注Around Advice定义所在的方法

1.AOP通知(配置xml文件)

QieMian1.java

public class QieMian1 {
    public void qianzhi(JoinPoint jp) {
        System.out.println("前置通知");
        Object [] os = jp.getArgs();
        for (Object object : os) {
            System.out.println("参数列表为:"+object);
        }
    }
    
    public void houzhi(Object a) {
        System.out.println("后置通知"+a);
    }
    
    public void yichang(JoinPoint jp,Throwable ta) {
        System.out.println("异常通知");
        ta.printStackTrace();
    }
    
    public void zuizhong() {
        System.out.println("最终通知");
    }
    
    public void huanrao(ProceedingJoinPoint pjp) {
        try {
            System.out.println("环绕前");
            pjp.proceed();
            System.out.println("环绕后");
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            System.out.println("环绕异常");
            e.printStackTrace();
        }finally {
            System.out.println("环绕最终");
        }
    }
}

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

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd ">          <!-- 配置文件的头信息使用AOP与IOC -->


<!-- 切面1 --> <bean id="qieMian1" class="com.zy.spring.tools.aop.QieMian1"></bean> <!-- 创建一个切面的bean --> <aop:config> <!-- aop配置标签 --> <aop:pointcut expression="execution(* com.zy.spring.service.*.*(..))" id="pc1"/> <!-- 创建一个切点 --> <aop:aspect order="1" ref="qieMian1"><!-- 创建一个切面 order是切面创建的顺序 ref链接上面创建的切面bean --> <aop:before method="qianzhi" pointcut-ref="pc1"/><!-- 前置通知 --> <aop:after-returning method="houzhi" pointcut-ref="pc1" returning="a"/> <!-- 后置通知 returning返回参数--> <aop:after-throwing method="yichang" pointcut-ref="pc1" throwing="ta"/> <!-- 异常通知 throwing返回参数--> <aop:after method="zuizhong" pointcut-ref="pc1"/> <!-- 最终通知 --> <aop:around method="huanrao" pointcut-ref="pc1"/> <!-- 环绕通知 --> </aop:aspect> </aop:config>
</beans>

常用的@AspectJ形式Pointcut表达式的标志符:

1、execution:
Spring AOP仅支持方法执行类型的Joinpoint 所以execution将会是我们用的最多的标志符,用它来帮我们匹配拥有指定方法前面的Joinpoint。

匹配方法execution

execution(返回类型 类的路径.类名.函数名(参数类型1,参数类型2))

execution(String com.chinasofti.Target.save(String))

execution(* com.chinasofti.Target.save(String))

execution(* com.chinasofti.*.save(String))

execution(* com.chinasofti.*.*(String))

execution(* com..*.*(..))


2、Within:
Within标志符只接受类型声明,它将匹配指定类型下所有的Joinpoint。

匹配类within

匹配到类
<aop:pointcut id="targetPintcut" expression="within(com.chinasofti.Target)"/>
调用这个类中的任何一个方法,都会走通知

匹配到包下的类
<aop:pointcut id="targetPintcut" expression="within(com.chinasofti.*)"/>
调用这个包下的任何一个类中的方法,都会走通知

匹配到包下及子包下的类
<aop:pointcut id="targetPintcut" expression="within(com..*)"/>
调用com这个包下的,所有子包及其一个类中的方法,都会走通知

2.AOP通知(注解配置)

QieMian2.java

@Aspect//定义切面
@Component//注册bean
public class QieMian2 {
    @Pointcut("execution(* com.zy.spring.service.*.*(..))") //标记切点规则
    public void pointcut() {};//创建一个空的方法,相当于切入方法
    
    @Before("pointcut()") //前置通知  切点就是上面创建的pointcut()方法
    public void qianzhi(JoinPoint jp) {
        System.out.println("注解前置通知");
        Object [] os = jp.getArgs();
        for (Object object : os) {
            System.out.println("参数列表为:"+object);
        }
    }
    @AfterReturning(pointcut="pointcut()",returning="a")//后置通知  returning是方法中定义的参数
    public void houzhi(Object a) {
        System.out.println("注解后置通知"+a);
    }
    @AfterThrowing(pointcut="pointcut()",throwing="ta")//异常通知  throwing是方法中定义的参数
    public void yichang(JoinPoint jp,Throwable ta) {
        System.out.println("注解异常通知");
        ta.printStackTrace();
    }
    @After("pointcut()")//最终通知
    public void zuizhong() {
        System.out.println("注解最终通知");
    }
    @Around("pointcut()")//环绕通知
    public void huanrao(ProceedingJoinPoint pjp) {
        try {
            System.out.println("注解环绕前");
            pjp.proceed();//放行
            System.out.println("注解环绕后");
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            System.out.println("注解环绕异常");
            e.printStackTrace();
        }finally {
            System.out.println("注解环绕最终");
        }
    }
}

ApplicationContext.xml

       <!-- 注解扫描AOP -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

使用注解aop功能,加入aop1的注解扫描即可。

猜你喜欢

转载自www.cnblogs.com/zhangyuan1024/p/12015130.html
今日推荐