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. 关于bind函数和connect函数的测试结论

    1. 一般客户端不用绑定,系统给你自动分配(有些ip不是固定的,bind也不是一个好方法):而服务器需要绑定,因为需要给客户端一个众所周知的固定的地址: 2. 关于bind错误,可以用WSAGetLa ...

  2. 泛型Binary Search Tree实现,And和STL map比较的经营业绩

    问题叙述性说明: 1.binary search tree它是一种二进制树的.对于key值.比当前节点左孩子少大于右子. 2.binary search tree不是自平衡树.所以,当插入数据不是非常 ...

  3. Java使用LdAP获取AD域用户

    随着我们的习大大上台后,国家在网络信息安全方面就有了非常明显的改变!所以如今好多做网络信息安全产品的公司和须要网络信息安全的公司都会提到用AD域server来验证,这里就简单的研究了一下! 先简单的讲 ...

  4. 2014在辛星Javascript口译科

    ***************概要*************** 1.Javascript是一种原型化继承的基于对象的动态类型的脚本语言,它区分大写和小写.主要执行在client,用户即使响应用户的操 ...

  5. 玩转web之servlet(六)---session介绍及简单使用(登录验证中保存信息)

    在浏览器与服务器进行交互时,往往需要把涉及到的一些数据保存下来,这时就需要使用cookie或session进行状态管理. 这篇文章先来说说session怎么用,首先在servlet中创建一个sessi ...

  6. JS 查找遍历子节点元素

    function nextChildNode(node,clazz,tagName){ var count= node.childElementCount; for(var i=0;i<coun ...

  7. Android 导入第三方jar时 出现ClassNotFoundException

    处理方式: 1.首先检查有没有正确的导入该jar和有没有重复导入该jar. 2.如果没有出现1的问题,那么在buildpath->order and export 中将你导入的jar左边的复选框 ...

  8. Swing中弹出对话框的几种方式(转)

    http://www.cnblogs.com/mailingfeng/archive/2011/12/28/2304289.html 在swing中,基于业务的考量,会有对话框来限制用户的行为及对用户 ...

  9. 妙用perfmon Alert抓dump

    抓dump文件,经常是解决众多疑难杂症的不二手段.但是很多时候,我们没办法抓.比如说 几秒内的线程数暴涨200个,然后迅速回落 程序跑了两天,内存涨到某个数字就自己OOM了 原因不外乎都是时间短,没有 ...

  10. Windows Phone 同步方式获取网络类型

    原文:Windows Phone 同步方式获取网络类型 在Windows Phone 开发中有时候需要获取设备当前连接网络的类型,是Wifi,还是2G,3G,或者4G,SDK中提供获取网络类型的API ...