文档章节

Spring AOP笔记

whc20011
 whc20011
发布于 2016/12/07 14:56
字数 1007
阅读 11
收藏 1
点赞 0
评论 0

 一、概念定义

     通知:定义了切面的"什么"和"何时"。

     切点:定义了切面的"何处"。用于准确定位应该在什么地方应用切面的通知。

     切面:切面是通知和切点的集合。

     连接点:在应用执行过程中能够插入切面的一个点。

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

二、使用切点选择连接点

    在Spring AOP中,需要使用AspectJ的切点表达式语言来定义切点。Spring仅支持AspectJ切点指示器的子集。其中只有execution指
示器是唯一的执行匹配,其他的指示器都是限制匹配的。

    1、切点的编写

        示例1:execution(* com.springinaction.springidol.Instrument.play(...))
                我们使用execution()指示器选择Instrument的play()方法。方法表达式以*号隔开,标识了我们不关心方法返回值的类型。然后,我们制订了全限定名和方法。方法中的(...)标识切点选择任意的play()方法,无论方法入参是什么。

    示例2:execution(* com.springinaction.springidol.Instrument.play(...)) && within(com.springinaction.spriingidol.*)
                我们使用within()指示器来限制切点仅匹配com.springinaction.springidol包。

三、在XML中声明切面

   1、 声明前置通知和后置通知:
    声明一个audience Bean:
    <bean id="audience" class="com.springinaction.springidol.Audience" />

    把audience Bean声明为一个切面:
    <aop : config>
        <aop : aspect ref="audience">
            <aop : before pointcut="execution(* com.springinaction.springidol.Performer(...))" method="takeSeats" />
            <aop : before pointcut="execution(* com.springinaction.springidol.Performer(...))" method="turnOffCellPhones" />
            <aop : after-returning  pointcut="execution(* com.springinaction.springidol.Performer(...))" method="applaud" />
            <aop : after-throwing pointcut="execution(* com.springinaction.springidol.Performer(...))" method="demandRefund" />
        </aop : aspect>
    </aop : config>

pointcut属性的值定义了通知应用的切点。pointcut属性的值是使用AspectJ切点表达式语法所定义的切点。

定义一个命名切点消除冗余的切点定义:
    
    <aop : config>
        <aop : aspect ref="audience">
            <aop : pointcut id="performance" expression="execution(* com.springinaction.springidol.Performer(...))">
            <aop : before pointcut-ref="performance" method="takeSeats" />
            <aop : before pointcut-ref="performance" method="turnOffCellPhones" />
            <aop : after-returning  pointcut-ref="performance" method="applaud" />
            <aop : after-throwing pointcut-ref="performance" method="demandRefund" />
        </aop : aspect>
    </aop : config>

 
  2、声明环绕通知
        这是环绕通知方法:
        public void watchPerformance(ProceedingJoinPoint  joinpoint){
            try{
                System.out.println("The audience is taking their seats.");                //表演之前
                System.out.println("The audience is turning off their cellphones.");

                joinpoint.proceed();                        //执行被通知的方法

                long end = System.currentTimeMillis();                        //表演之后
                System.out.println("CLAP CLAP CLAP CLAP CLAP CLAP ");
                System.out.println("The performance took " + (end - start));
            }catch(Throwable t){
                 System.out.println("Boo! we want our money back!");               //表演失败之后
             }
        }

        该通知方法使用了ProceedingJoinPoint作为方法的入参,该对象能让我们在通知里调用被通知的方法。
        如果我们忘记调用proceed()方法,通知将会阻止被通知方法的调用。
        在此audience切面,watchPerformance()方法包含之前4个通知方法的所有逻辑,但所有逻辑都放在一个方法中了。

    声明环绕通知:
    <aop : config>
        <aop : aspect ref="audience">
            <aop : pointcut id="performance2" expression="execution(* com.springinaction.springidol.Performer(...))">
            <aop : around pointcut-ref="performance" method="watchPerformance()" />
        </aop : aspect>
    </aop : config>

3、为通知传递参数
 
有时候通知并不仅仅是对方法进行简单的包装,还需要检验传递给方法的参数值,这时候为通知传递参数就非常有用了。

四、注解切面

    1、注解前置、后置通知:

    package  com.springinaction.springidol;

    @Aspect                                                             
    public class Audience {
        @Pointcut(                                                   //定义切点
                        "execution(* com.springincation.springidol.Performer.perform( .. ))")
    public void performance(){
    }
    
    @Before("performance()")                            //表演之前
    public void takeseats(){
        System.out.println("The audience is taking their seats.");
   
    @Before("performance()")                           //表演之前
    public void turnoffCellPhones(){
        System.out.println("The audience is turning off their cellphones.");
    
    
    @AfterReturning("performance()")            //表演之后
    public void applaud(){
        System.out.println("CLAP CLAP CLAP CLAP CLAP");

    @AfterThrowing("performance()")            //表演失败之后
    public void demandRefund(){
        System.out.println("Boo! We want our money back!");
    }
    }

    新的Audience类使用@AspectJ注解进行了标注。该注解标注了Audience不仅仅是一个POJO,还是一个切面。

    @pointCut注解用于定义一个可以在@AspectJ切面内可重用的切点。切点的名称来源于注解所应用的方法名称。因此该切点名称为performance()。performance()方法在这里是空的,该方法本身只是一个标识,供@pointCut注解依附。

2、注解环绕通知:

    @Around("performance()")
    public void watchPerformance(ProceedingJoinPoint joinpoint){
        try{
            System.out.println("The audience is taking their seats.");
            System.out.println("The audience is turning off their cellphones.");
            
            long start = System.currentTimeMillis();
            joinpoint.proceed();
            long end = System.currentTimeMillis();

            System.out.println("CLAP CLAP CLAP CLAP CLAP !");
            System.out.println("The performance took" + (end - start) + "milliseconds");
        }catch(Throwable t ){
            System.out.println("Boo! We want our money back!");
        }
    }
 

© 著作权归作者所有

共有 人打赏支持
whc20011
粉丝 0
博文 52
码字总数 29810
作品 0
朝阳
程序员
《Spring Recipes》第三章笔记1:Enabling AspectJ Annotation

《Spring Recipes》第三章笔记:Enabling AspectJ Annotation 问题 如何开启Spring容器对AspectJ注解的支持。 解决方案 在配置文件中引入aop schema,添加<aop:aspectj-autoproxy />配置。 ...

LiJIaming
2012/05/20
0
0
spring第三天SSH整合笔记

spring事务管理 * Spring事务管理高层抽象主要包括3个接口 1)PlatformTransactionManager 事务管理器 ,用于管理事务 2)TransactionDefinition 事务定义信息(隔离、传播、超时、只读)---静...

dh_
2014/04/22
0
0
Spring笔记4---前置后置通知

开始聊聊注解! Spring切面可以应用5种类型的通知: 1 Before---在方法被调用之前调用通知 2 After--- 在方法完成之后调用通知,无论方法执行是否成功 3 After-returning---在方法成功执行之...

强子哥哥
2015/01/11
0
0
Spring笔记5---环绕通知

Spring的环绕通知 ---------------------------- package com.springinaction.springidol; import org.aspectj.lang.ProceedingJoinPoint; public class Audience { public void takeSeats()......

强子哥哥
2015/01/11
0
0
Spring实战读书笔记(1)

Spring的根本使命是? 简化Java开发 为了降低Java开发的复杂性,Spring采取了哪4种关键策略? 1、基于POJO的轻量级和最小侵入性编程 2、通过依赖注入和面向接口实现松耦合 3、基于切面和惯例...

祥林会跟你远走高飞
2014/12/30
0
0
Spring3.2.4 和 MyBatis 整合笔记

涉及内容: Spring 和 MyBatis 的整合 Annotation的事务管理 响应流程 需要的lib文件: spring 版本:spring-framework-3.1.0.RELEASE MyBatis 版本: mybatis-3.0.6 注意:请用这以上或是更高...

LIPING234
2013/10/14
0
2
Spring中的AOP(二)——AOP基本概念和Spring对AOP的支持

AOP的基本概念 AOP从运行的角度考虑程序的流程,提取业务处理过程的切面。AOP面向的是程序运行中的各个步骤,希望以更好的方式来组合业务逻辑的各个步骤。AOP框架并不与特定的代码耦合,AOP...

摆渡者
2014/03/17
0
3
Aspectj与Spring AOP比较

1、简介 今天有多个可用的 AOP 库, 它们需要能够回答许多问题: 是否与用户现有的或新的应用程序兼容? 在哪里可以实现 AOP? 与自己的应用程序集成多快? 性能开销是多少? 在本文中, 我们将...

沈渊
04/18
0
0
Spring笔记2---DI

工厂注入: <bean id="xxx" class="x.x.x" factory-method="methodName" /> Bean的作用域 <bean id="xxx" class="x.x.x" scope="scope" /> scope="prototype"---每次都产生一个新的实例 scop......

强子哥哥
2015/01/10
70
0
Spring Aop配置时的切入点表达式

对应的中文: 任意公共方法的执行: execution(public (..)) 任何一个以“set”开始的方法的执行: execution( set(..)) AccountService 接口的任意方法的执行: execution( com.xyz.service...

cswy
2013/12/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

RESTful API 设计规范

关于「能愿动词」的使用 为了避免歧义,文档大量使用了「能愿动词」,对应的解释如下: 必须 (MUST):绝对,严格遵循,请照做,无条件遵守; 一定不可 (MUST NOT):禁令,严令禁止; 应该 (S...

niithub
5分钟前
0
0
Spring Cloud云服务架构 - common-service 项目过程构建

我们将对common-service整个项目进行剖析,将整个构建的流程给记录下来,让更多的关注者来参考学习。 首先在构建spring cloud的common-service之前,我们需要准备的技术: Maven(项目构建)...

itcloud
6分钟前
0
0
oracle 如何查看日志?

Oracle日志查看一.Oracle日志的路径:登录:sqlplus "/as sysdba"查看路径:SQL> select * from v$logfile;SQL> select * from v$logfile;(#日志文件路径)二.Oracle日...

youfen
7分钟前
0
0
sap netweaver developer studio安装svn插件

问题 我现在在Sap的IDE(netweaver developer studio)上面安装svn插件。 步骤 确定IDE使用的eclipse版本 Help→About SAP NetWeaver Developer Studio→Installation Details→Features→F...

亚林瓜子
13分钟前
0
0
大数据开发学习的内容介绍,成都大数据培训机构哪里好?

大数据开发培训已经成为了越来越多人的选择,大数据开发工程师也是各公司争相争夺的金领人才之一了,在当今科技发展非常迅速的社会里,越来越多人把职业规划投向了大数据开发。这里为大家整理...

加米谷大数据
18分钟前
2
0
函数

函数 函数是Python中最主要也是最重要的代码组织和复用手段。作为最重要的原则,如果你要重复使用相同或非常类似的代码,就需要写一个函数。通过给函数起一个名字,还可以提高代码的可读性。...

火力全開
20分钟前
0
0
gulp-webserverf启动服务,局域网无法访问

如题,gulp-server启动的服务,只能本机访问,局域网通过ip无法访问; 启动的其它项目,均可以访问成功; 网上资源,很多说什么防火墙之类的问题,都无果; 只需要给启动服务添加参数即可, ...

littleFaye
22分钟前
0
0
RabbitMQ实战:5种模式和示例

应用RabbitMQ的5种队列 一、简单队列 P:消息的生产者 C:消息的消费者 红色:队列 生产者实现思路: 创建连接工厂ConnectionFactory,设置服务地址127.0.0.1,端口号5672,设置用户名、密码...

spinachgit
23分钟前
0
0
mysql常见报错标号对应原因以及处理方法

mysql常见报错标号以及对应解决方法 报错标号 报错现象 解决方法 原因 1449 Cause: java.sql.SQLException: The user specified as a definer ('authplat_dev'@'%') does not exist 在控制台...

ChinaHYF
25分钟前
0
0
Java 监控系统技术选型

(1)操作系统监控 Sigar oshi (2)Tomcat监控 JMX 日志 (3)Oracle监控 日志 直连SQL查询 基于Druid连接池 (4)拓扑图 jtopo http://www.jtopo.com/demo/statictis.html...

cccyb
26分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部