6月14日,阴转雨。

“四面垂杨十里荷,向云何处最花多, 画楼南畔夕阳和。天气乍凉人寂寞, 光阴须得酒消磨,且来花里听笙歌。”

面向切面的框架AspectJ邂逅Spring,不仅造就一种简洁,更带来很多其它的选择空间。

上篇的切面与代理配置方式。麻烦且繁琐。好在Spring 与 AspectJ 进行了集成,从接口和配置的泥潭爬出,善莫大焉。

以下把上一篇Spring的AOP 的样例改写一下,达到相同的效果。

1-3步骤不变。

       4、定义一个 Aspect 切面类BallHandler.java

package edu.eurasia.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.AfterReturning; @Aspect
public class BallHandler {
static Logger logger = Logger.getLogger(TestBall.class); @Pointcut("execution(* edu.eurasia.aop.WatchBallImpl.watchfoot*(..))")
public void watchfootball(){}; @Pointcut("execution(* edu.eurasia.aop.WatchBallImpl.watchbasket*(..))")
public void watchbasketball(){}; @Before(value="watchfootball()&& args(city,..)")
public void watchBefore(String city){
logger.debug(" 看球前,先去 " + city + " 咖啡馆喝杯巴西咖啡 ...");
} @AfterReturning("watchbasketball() && args(city,..)")
public void watchAfter(String city){
logger.debug("看完球去 " + city + " 麦当劳吃汉堡包! "); }
}<span style="background-color: rgb(255, 255, 255);">
</span>

类上面标注的 @Aspect 注解。这表明该类是一个 Aspect(事实上就是 Advisor)-切面类。

该类无需实现不论什么的接口,仅仅需定义一个方法(方法叫什么名字都无所谓)。

@Pointcut使用这种方法能够将edu.eurasia.aop.WatchBallImpl.watchfoot*(..)方法声明为poincut即切入点。作用,在watchfoot*(..)方法被调用的时候运行watchfootball()方法。当中execution是匹配方法运行的切入点。也就是spring最经常使用的切入点定义方式。

@Before(value="watchfootball()&& args(city,..)):@Before声明为在切入点方法运行之前运行,而后面没有直接声明切入点,而是value="watchfootball()",是由于假设@afterReturning等都有所修改的时候都必须所有修改。所以统一用Pointcut的watchfootball取代,这样子有修改的时候仅需修改一个地方。其他@AfterReturning类同。&&
args(city,..)能够获取切入点方法watchfoot*(..)的參数。

以下分析一下这个切点表达式:

execution(* edu.eurasia.aop.WatchBallImpl.watchfoot*(..))

  • execution():表示拦截方法,括号里可定义须要匹配的规则。

  • 第一个“*”:表示方法的返回值是随意的。

  • 第二个“*”:表示匹配该类中全部的方法。

  • (..):表示方法的參数是随意的。

5、编写spring的配置文件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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
> <!-- 定义Aspect -->
<bean id="ballHandler" class="edu.eurasia.aop.BallHandler" /> <!-- 定义Common -->
<bean id="watchBall" class="edu.eurasia.aop.WatchBallImpl" /> <!-- 启动AspectJ支持 -->
<aop:aspectj-autoproxy />
</beans>

6、编写測试类TestBall.java

package edu.eurasia.aop;

import org.apache.log4j.Logger;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestBall {
static Logger logger = Logger.getLogger(TestBall.class); @Test
public void testball() { logger.debug("test begin "); ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml"); WatchBall watchball = (WatchBall) ctx.getBean("watchBall"); watchball.watchfootball("里约热内卢"); logger.debug("----------------------------"); watchball.watchbasketball("德克萨斯州");
}
}

7、执行结果和环境配置

执行结果例如以下:

DEBUG [main] (BallHandler.java:21) -  看球前,先去  里约热内卢  咖啡馆喝杯巴西咖啡 ...

DEBUG [main] (WatchBallImpl.java:11) - 去 里约热内卢 看2014巴西世界杯

DEBUG [main] (TestBall.java:25) - ----------------------------

DEBUG [main] (WatchBallImpl.java:16) -  去德克萨斯州 看2014NBA总决赛

DEBUG [main] (BallHandler.java:26) - 看完球去  德克萨斯州  麦当劳吃汉堡包。

本例使用spring 2.5.6,除了找出spring.jar。commons-logging-1.1.1.jar两个jar包,外加一个log4j.jar。还要下载aspectj-1.7.0.jar。解压后有四个JAR:aspectjrt.jar,aspectjtools.jar,aspectjweaver.jar和org.aspectj.matcher.jar。还须要下载一个aopalliance-1.0.jar。

文件夹结构例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvendzendz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

8、基于配置的AspectJ

除了使用 @Aspect 注解来定义切面类以外,Spring AOP 也提供了基于配置的方式来定义切面类。

(1) 配置文件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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> <!-- 定义Aspect -->
<bean id="ballHandler" class="edu.eurasia.aop.BallHandler" /> <!-- 定义Common -->
<bean id="watchBall" class="edu.eurasia.aop.WatchBallImpl" /> <aop:config>
<aop:aspect ref="ballHandler">
<aop:before method="watchBefore" arg-names="city"
pointcut="execution(* edu.eurasia.aop.WatchBallImpl.watchfoot*(String,..)) and args(city,..)" />
<aop:after method="watchAfter" arg-names="city"
pointcut="execution(* edu.eurasia.aop.WatchBallImpl.watchbasket*(String,..)) and args(city,..)" />
</aop:aspect>
</aop:config>
</beans>

(String,..)声明切入点至少含有一个String类型的參数。显然能够匹配WatchBallImpl中的watchfoot*(String city,..);args(n,..)声明给watchfoot*(String city,..)的第一个參数起了个别名“n”传递给Advice,假设<aop:before...>中arg-names不是“n”,将抛出异常。

(2) BallHandler.java 代码变化不大:

package edu.eurasia.aop;

import org.apache.log4j.Logger;  

public class BallHandler {
static Logger logger = Logger.getLogger(TestBall.class); public void watchBefore(String city){
logger.debug(" 看球前。先去 " + city + " 咖啡馆喝杯巴西咖啡 ...");
} public void watchAfter(String city){
logger.debug("看完球去 " + city + " 麦当劳吃汉堡包!"); }
}

(3)其余代码和配置不变,执行结果同样。

版权声明:本文博主原创文章,博客,未经同意不得转载。

二十9天 月出冲击黑鸟 —Spring的AOP_AspectJ @annotation的更多相关文章

  1. Spring Boot入门系列(二十六)超级简单!Spring Data JPA 的使用!

    之前介绍了Mybatis数据库ORM框架,也介绍了使用Spring Boot 的jdbcTemplate 操作数据库.其实Spring Boot 还有一个非常实用的数据操作框架:Spring Data ...

  2. 二十六:Struts2 和 spring整合

    二十六:Struts2 和 spring整合 将项目名称为day29_02_struts2Spring下的scr目录下的Struts.xml文件拷贝到新项目的scr目录下 在新项目的WebRoot-- ...

  3. spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求

    spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求 有半年多没有更新了,按照常规剧本,应该会说项目很忙,工作很忙,没空更新,吧啦吧啦,相关的话吧, 但是细想想 ...

  4. Spring Boot(二十):使用spring-boot-admin对spring-boot服务进行监控

    Spring Boot(二十):使用spring-boot-admin对spring-boot服务进行监控 Spring Boot Actuator提供了对单个Spring Boot的监控,信息包含: ...

  5. SpringBoot开发二十-Redis入门以及Spring整合Redis

    安装 Redis,熟悉 Redis 的命令以及整合Redis,在Spring 中使用Redis. 代码实现 Redis 内置了 16 个库,索引是 0-15 ,默认选择第 0 个 Redis 的常用命 ...

  6. 设计模式学习(二十四):Spring 中使用到的设计模式

    设计模式学习(二十四):Spring 中使用到的设计模式 作者:Grey 原文地址: 博客园:设计模式学习(二十四):Spring 中使用到的设计模式 CSDN:设计模式学习(二十四):Spring ...

  7. Spring源码分析(二十二)功能扩展

    摘要: 本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 目录 一.增加SPEL语言的支持 二.增加属性注册编辑器 1. 使用自 ...

  8. SpringBoot进阶教程(二十六)整合Redis之共享Session

    集群现在越来越常见,当我们项目搭建了集群,就会产生session共享问题.因为session是保存在服务器上面的.那么解决这一问题,大致有三个方案,1.通过nginx的负载均衡其中一种ip绑定来实现( ...

  9. SpringBoot进阶教程(二十五)整合Redis之@Cacheable、@CachePut、@CacheEvict的应用

    在上一篇文章(<SpringBoot(二十四)整合Redis>)中,已经实现了Spring Boot对Redis的整合,既然已经讲到Cache了,今天就介绍介绍缓存注解.各家互联网产品现在 ...

随机推荐

  1. BZOJ 1975 SDOI2010 魔法猪学院 A*k短路

    题目大意:给定一个值E 求起点到终点的最多条路径 使长度之和不超过E k短路的A*算法--每一个点有一个估价函数=g[x]+h[x] 当中g[x]是从源点出发已经走了的长度 h[x]是从这个点到汇点的 ...

  2. lua简洁的功能(两)

    Lua中的函数带有词法定界的第一类值. 第一类值: 在Lua中,函数和其它值(数值,字符串)一样,函数能够被存放在变量中,也存放在表中, 能够作为函数的參数,还能够作为函数的返回值. 词法定界:被嵌套 ...

  3. Chromium

    Chromium多进程架构 多进程架构 转载请注明出处:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//Start_Here_Bac ...

  4. C语言中的static 具体分析

    google了近三页的关于C语言中static的内容,发现可用的信息非常少,要么长篇大论不知所云要么在关键之处几个字略过,对于想挖掘底层原理的刚開始学习的人来说參考性不是非常大.所以,我这篇博文博採众 ...

  5. HDU 4777 Rabbit Kingdom(树状数组)

    HDU 4777 Rabbit Kingdom 题目链接 题意:给定一些序列.每次询问一个区间,求出这个区间和其它数字都互质的数的个数 #include <cstdio> #include ...

  6. ShareSDK for Android 2.3.8它已发表

    ShareSDK for Android 2.3.8已经公布,本次更新内容包含: 1.一键分享加入"摇一摇截图分享"功能 3.优化一键分享截图分享功能 4.一键分享编辑页界面微调 ...

  7. 懒与馋的平衡:餐饮O2O市场广阔,发展不易

    餐饮行业是众多行业中O2O起步较早的,现在方兴未艾的团购站点中最先涉足的领域就有餐饮版块.长时间的合作推广,很多餐饮商家已经从中尝到甜头,可以说餐饮行业市场基础培育的比較好,所以餐饮O2O 已经是大势 ...

  8. XML文件编码问题

    这两天的过程中的一个项目,以解决编码格式ANSI的xml当文件.我遇到了一些问题.下面的例子现在将总结分析过程. 通过win7记事本或notepad++创建一个xml文件test_source: &l ...

  9. Xcode 凝视代码

    #pragma mark ---------------凝视信息-------------------- -(void)RequestSP { // MARK: 凝视信息 // TODO: 凝视信息 ...

  10. 【JAVA】【NIO】3、Java NIO Channel

    Java NIO和流量相似,但有些差异: ·通道可读写,流仅支持单向.读或写 ·异步通道读取 ·通道读写器,他们是和Buffer交替 道的实现 下面是Java NIO中最重要的通道的实现: ·File ...