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. python之字符串的分割和拼接

    关于string的split 和 join 方法 对导入os模块进行os.path.splie()/os.path.join() 貌似是处理机制不一样,但是功能上一样. 1.string.split( ...

  2. postgresql数据库配置csv格式的日志输出

    postgresql数据库配置csv格风格日志输出 以下介绍postgresql数据库中关于csv格式日志(pg中一种比較具体的日志输出方式)的设置方法. 1.进入$PGDATA文件夹(pg的安装文件 ...

  3. QQ旅程server分析01-网关server

    网关server网络进程: s1.连接网关管理器 s2.上报自身信息给网关管理器 s3.从网关管理器获取自己的管理信息 *s4.依照管理信息预分配好须要的资源 s5.网关server打开client监 ...

  4. Cluster Table

    对簇表来说,总是要先创建簇段(cluster segment).然后将表关联到cluster segment里.由此可知,簇表也是虚拟表,没有对应的segment,簇表对应的是cluster segm ...

  5. bootstrap的popover在trigger设置为hover时不隐藏popover

    使用bootstrap的popover,trigger设置为hover时,可以实现当鼠标放置到目标元素上时显示popover,可是无法实现当鼠标移动到popover上时不隐藏popover,在网上找了 ...

  6. 【HDU】5256 系列转换(上涨时间最长的序列修饰)

    假设a[i]和a[j]我想的一样,满足条件的需要是 a[j] - a[i] > j - i 也就是说,a[i] - i < a[j] - j 例1 4 2 不满意,所以1和2必须有必要之间 ...

  7. 区间第K大

    protected static int partitions(List<KDNode> data,int left,int right,int k,int pos){ int l = l ...

  8. 产品经理(五岁以下儿童)myVegas Slots排名上升的秘密

    myVEGAS Slots于AppStore上排名在今年也就是2月份时候飙升,那么什么情况导致这个现象的呢,我们试图通过App Annie的分析给出答案. 上面是myVegas的排名情况,我们能够看到 ...

  9. iOS缓存类的设计

    使用执行速度缓存的程序可以大大提高程序,设计一个简单的缓存类并不需要太复杂的逻辑. 只需要一个简单的3接口. 存款对象 以一个对象 删除对象 阅读对象 watermark/2/text/aHR0cDo ...

  10. unity3d插入Daikon Forge GUI 中国课程-7-高级控制slider采用

    (游戏开始的牛市)大家好我是孙广东.官方网站提供的是专业的视频教程http://www.daikonforge.com/dfgui/tutorials/,只是是在youtube上,要观看是须要FQ的. ...