基于<aop:aspect>与<aop:advisor>的区别

目录
  • 1、实现方式不同
  • 2、使用场景不同
  • 小结

在开发过程中,不少有Spring Aop的使用,在面向切面编程时,我们会使用< aop:aspect>;在进行事务管理时,我们会使用< aop:advisor>。那么,对于< aop:aspect>与< aop:advisor>的区别,具体是怎样的呢?

至于两者的区别,网上有很多资料,但是似乎都不能说清楚。

首先,我们需要明确两者的概念。

  • < aop:aspect>:定义切面(切面包括通知和切点)
  • < aop:advisor>:定义通知器(通知器跟切面一样,也包括通知和切点)

下面,我们列举两者的几个区别。

1、实现方式不同

< aop:aspect>定义切面时,只需要定义一般的bean就行,而定义< aop:advisor>中引用的通知时,通知必须实现Advice接口。

下面我们举例说明。

首先,我们定义一个接口Sleepable和这个接口的实现Human,代码如下:

public interface Sleepable {
    public void sleep();
}
public class Human implements Sleepable {
    @Override
    public void sleep() {
        System.out.println("我要睡觉了!");
    }
}

下面是< aop:advisor>的实现方式:

//定义通知
public class SleepHelper implements MethodBeforeAdvice,AfterReturningAdvice{
    @Override
    public void before(Method arg0, Object[] arg1, Object arg2)
            throws Throwable {
        System.out.println("睡觉前要脱衣服!");
    }
    @Override
    public void afterReturning(Object arg0, Method arg1, Object[] arg2,
            Object arg3) throws Throwable {
        System.out.println("起床后要穿衣服!");
    }
}
//aop配置
<bean id="sleepHelper" class="com.ghs.aop.SleepHelper"></bean>
<aop:config>
    <aop:pointcut expression="execution(* *.sleep(..))" id="sleepPointcut"/>
    <aop:advisor advice-ref="sleepHelper" pointcut-ref="sleepPointcut"/>
</aop:config>
<bean id="human" class="com.ghs.aop.Human"/>

下面是< aop:aspect>的实现方式:

//定义切面
public class SleepHelperAspect{
    public void beforeSleep(){
        System.out.println("睡觉前要脱衣服!");
    }
    public void afterSleep(){
        System.out.println("起床后要穿衣服!");
    }
}
//aop配置
<bean id="sleepHelperAspect" class="com.ghs.aop.SleepHelperAspect"></bean>
<aop:config>
    <aop:pointcut expression="execution(* *.sleep(..))" id="sleepPointcut"/>
    <aop:aspect ref="sleepHelperAspect">
        <!--前置通知-->
        <aop:before method="beforeSleep" pointcut-ref="sleepPointcut"/>
        <!--后置通知-->
        <aop:after method="afterSleep" pointcut-ref="sleepPointcut"/>
    </aop:aspect>
</aop:config>
<bean id="human" class="com.ghs.aop.Human"/>

测试代码如下:

public class TestAOP {
    public static void main(String[] args) {
        method1();
//      method2();
    }
    private static void method1() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext1.xml");
        Sleepable sleeper = (Sleepable) context.getBean("human");
        sleeper.sleep();
    }
    private static void method2() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml");
        Sleepable sleeper = (Sleepable) context.getBean("human");
        sleeper.sleep();
    }

//执行结果

睡觉前要脱衣服!

我要睡觉了!

起床后要穿衣服!

}

2、使用场景不同

< aop:advisor>大多用于事务管理。

例如:

<!-- 会重复读,不会脏读事务 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="*" timeout="120" propagation="REQUIRED" rollback-for="Exception" />
    </tx:attributes>
</tx:advice>
<aop:config proxy-target-class="true">
    <aop:pointcut id="txPointCut" expression="..."/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut" />
</aop:config>

< aop:aspect>大多用于日志,缓存

其实,不管是< aop:advisor>还是< aop:aspect>最终的实现逻辑是一样的。

小结

可以看出,< aop:advisor>和< aop:aspect>其实都是将通知和切面进行了封装,原理基本上是一样的,只是使用的方式不同而已。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Spring基于advisor配置aop过程解析

    1.目标类 package com.gec.target; public class Hadoop { public void eatting() { System.out.println("大象正在吃东西 1"); try { //耗时5秒 Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } } 2.增强类,此类必须要实现增强方位接口 package com.gec.advic

  • Spring boot AOP通过XML配置文件声明

    通过 XML 配置文件声明 在前两篇博文和示例中,我们已经展示了如何通过注解配置去声明切面,下面我们看看如何在 XML 文件中声明切面.下面先列出 XML 中声明 AOP 的常用元素: AOP配置元素 用途 aop:advisor 定义AOP通知器 aop:after 定义AOP后置通知(不管被通知的方法是否执行成功) aop:after-returning 定义AOP返回通知 aop:after-throwing 定义AOP异常通知 aop:around 定义AOP环绕通知 aop:aspec

  • Spring AspectJ AOP框架注解原理解析

    什么是AspectJ AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件. AspectJ是一个基于Java语言的AOP框架 Spring2.0以后新增了对AspectJ切点表达式支持 @AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面 新版本Spring框架,建议使用AspectJ方式来开发AOP AspectJ表达式: 语法:exe

  • 基于<aop:aspect>与<aop:advisor>的区别

    目录 1.实现方式不同 2.使用场景不同 小结 在开发过程中,不少有Spring Aop的使用,在面向切面编程时,我们会使用< aop:aspect>:在进行事务管理时,我们会使用< aop:advisor>.那么,对于< aop:aspect>与< aop:advisor>的区别,具体是怎样的呢? 至于两者的区别,网上有很多资料,但是似乎都不能说清楚. 首先,我们需要明确两者的概念. < aop:aspect>:定义切面(切面包括通知和切点)

  • 基于spring中的aop简单实例讲解

    aop,即面向切面编程,面向切面编程的目标就是分离关注点,比如:一个骑士只需要关注守护安全,或者远征,而骑士辉煌一生的事迹由谁来记录和歌颂呢,当然不会是自己了,这个完全可以由诗人去歌颂,比如当骑士出征的时候诗人可以去欢送,当骑士英勇牺牲的时候,诗人可以写诗歌颂骑士的一生.那么骑士只需要关注怎么打仗就好了.而诗人也只需要关注写诗歌颂和欢送就好了,那么这样就把功能分离了.所以可以把诗人当成一个切面,当骑士出征的前后诗人分别负责欢送和写诗歌颂(记录).而且,这个切面可以对多个骑士或者明人使用,并不只局

  • 聊聊注解@Aspect的AOP实现操作

    Spring只支持XML方式而没有实现注解的方式(也叫AspectJ方式)的AOP,所以要使用@Aspect注解,只能引入AspectJ相关的 jar 包 aopalliance-1.0.jar 和 aspectjweaver.jar,这个坑把我给坑惨了. 使用步骤如下: 1.引入相关jar包 2.Spring的配置文件 applicationContext.xml 中引入context.aop对应的命名空间:配置自动扫描的包,同时使切面类中相关方法中的注解生效,需自动地为匹配到的方法所在的类生

  • .NET Core基于EMIT编写的轻量级AOP框架CZGL.AOP

    目录 1,快速入门 1.1继承ActionAttribute特性 1.2标记代理类型 2,如何创建代理类型 通过API直接创建 2,创建代理类型 通过API 通过Microsoft.Extensions.DependencyInjection 通过Autofac 3,深入使用 代理类型 方法.属性代理 上下文 拦截方法或属性的参数 非侵入式代理 Nuget 库地址:https://www.nuget.org/packages/CZGL.AOP/ Github 库地址:https://github

  • ThinkPHP5 框架引入 Go AOP,PHP AOP编程项目详解

    本文实例讲述了ThinkPHP5 框架引入 Go AOP,PHP AOP编程.分享给大家供大家参考,具体如下: 项目背景 目前开发的WEB软件里有这一个功能,PHP访问API操作数据仓库,刚开始数据仓库小,没发现问题,随着数据越来越多,调用API时常超时(60s).于是决定采用异步请求,改为60s能返回数据则返回,不能则返回一个异步ID,然后轮询是否完成统计任务.由于项目紧,人手不足,必须以最小的代价解决当前问题. 方案选择 重新分析需求,并改进代码 采用AOP方式改动程序 从新做需求分析,以及

  • 基于python中staticmethod和classmethod的区别(详解)

    例子 class A(object): def foo(self,x): print "executing foo(%s,%s)"%(self,x) @classmethod def class_foo(cls,x): print "executing class_foo(%s,%s)"%(cls,x) @staticmethod def static_foo(x): print "executing static_foo(%s)"%x a=A(

  • 基于js中this和event 的区别(详解)

    今天在看javascript入门经典-事件一章中看到了 this 和 event 两种传参形式.因为作为一个初级的前端开发人员平时只用过 this传参,so很想弄清楚,this和event的区别是什么,什么情况下用什么比较合适. onclick = changeImg(this)       vs     onclick = changeImg(event) <img src='usa.gif' onclick="changeImg(event)" /> <scrip

  • 基于Java中throw和throws的区别(详解)

    系统自动抛出的异常 所有系统定义的编译和运行异常都可以由系统自动抛出,称为标准异常,并且 Java 强烈地要求应用程序进行完整的异常处理,给用户友好的提示,或者修正后使程序继续执行. 语句抛出的异常 用户程序自定义的异常和应用程序特定的异常,必须借助于 throws 和 throw 语句来定义抛出异常. throw是语句抛出一个异常. 语法:throw (异常对象); throw e; throws是方法可能抛出异常的声明.(用在声明方法时,表示该方法可能要抛出异常) 语法:[(修饰符)](返回

  • 基于substring()和substr()的使用以及区别(实例讲解)

    在JavaScript中,通常会用到截取,那所谓截取呢,其实就是要获得被截取元素的某个位置到某个位置的内容,那么JS给我提供了substring和substr这两种方法: 这两种截取的方式有什么区别呢?直接代码演示: substring(a,b): a:表示起始位置 b:表示结束位置 !但是值得注意的是:截取时,截取内容当中包含了开始位置的元素,但是不包含结束位置的元素! 示例: function sub1(){ var str = 'javascript'; return str.substr

  • 基于Python中capitalize()与title()的区别详解

    capitalize()与title()都可以实现字符串首字母大写. 主要区别在于: capitalize(): 字符串第一个字母大写 title(): 字符串内的所有单词的首字母大写 例如: >>> str='huang bi quan' >>> str.capitalize() 'Huang bi quan' #第一个字母大写 >>> str.title() 'Huang Bi Quan' #所有单词的首字母大写 非字母开头的情况: >>

随机推荐