3.AOP

2019-04-23  本文已影响0人  9156523

面向切面的Spring

在一般的程序开发中,在每一个功能模块中都有相同的操作,例如打印日志,事务操作等一系列重复动作,而Spring AOP指的就是把这种重复工作横向抽取出来,让程序员只需要关注业务

下面是关于AOP的相关术语

通知:简而言之就是被抽取出来的方法

连接点:可以插入通知的点

切点:需要被插入通知的点

切面:切点和通知构成了一个切面

织入:把切面应用到目标对象并创建新的代理对象过程

使用注解的方式定义切面

可以在类前使用@Aspect,代表这个是个切面类,一下代表的是在perform方法调用之前执行这个方法

@Aspect
public class Audience{

@Before("execution (** concert.Performace.perform(..))")
public void silenceCellPhones(){
    System.out.prinln("Silencing cell phones");
}

}

如果相同的切点被频繁的使用,可以使用@pointcut,被定义为@Pointcut的实际方法内容不重要,他只是作为一个标识

public class Audience{
@Pointcut("execution (** concert.Performance.perform(..))")
public void performance(){}

@Before("performance()")
public void silenceCellPhones(){
    System.out.println("aa");
}

}

定义了切面类以后,需要使用配置来自动装配被@Aspect修饰的类

使用JavaConfig启动自动代理

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class ConcertConfig{
    @Bean
    public Audience audience(){
        return new Audience();
    }
}

使用xml

<context:component-scan base-package="concert" />
<aop:aspectj-autoproxy /> 启动AspectJ自动代理

在xml中声明切面

在前面所说的切面定义中,使用java配置优于xml配置,但是java配置的缺点就是必须要有源码,所以,了解在xml中声明切面是必须的


<aop:config>

<aop:aspect ref="Bean"> <!--引用一个切面类-->

<!--before 前置通知-->
<!--pointcut切入点,代表需要被插入通知的方法的地方-->
<!--method 通知,代表插入的方法 -->
<aop:before 
    pointcut="execution(** 包名.类名.方法名(..))" 
    method="insertMethod" //通知
/>

同理 before改成after-returning代表后置通知,且方法被执行完成以后才会执行

after代表无论方法是否执行成功都会执行
after-thorwing代表抛出异常以后会执行的方法
</aop:config>

如果多个通知都是在同一个切点,这样就要重复写很多同样的pointcut,我们可以为切点命名,如下,这样我们就可以使用pointcut-ref直接指定id号获取切点,如果想要这个切点可以被所有切面所引用,可以把这个节点放在config下

<aop:config>
<aop:aspect ref="audience">
<aop:pointcut id="idName" expression="execution ..."
</aop:aspect>
</aop:config>

环绕通知

环绕通知指的是 既可以执行前置通知 然后在执行被通知方法,最后在执行后置通知,环绕通知的好处是因为环绕通知是一个方法,所以变量是共享的,如果使用前置和后置通知,你在前置通知中定义的变量肯定是不能被后置通知访问的

环绕通知必须有参数,因为需要调用被通知函数


public void roundMethod(ProceedingJoinPoint jp){
    try{
        //前置方法
        System.out.println("前置方法")
        jp.proceed();//调用被通知方法
        System.out.println("后置方法")
    }catch(Exception e){
        System.out.println("异常之后的方法");
    }

}

<aop:config>
    <aop:aspect ref="aspectBean">
        <aop:pointcut id="idName"
        expression ="execution(** 包名.类名.方法(..))"
        method ="roundMethod"
    </aop:aspect>
<aop:config>

通过以上就可以达到前置、后置、异常的通知 织入到切点中

上一篇下一篇

猜你喜欢

热点阅读