SpringAOP 处理通知中的参数(注解与xml配置)
来源:互联网 发布:mac怎样建立文件夹 编辑:程序博客网 时间:2024/06/07 02:21
上一篇文章讲的是springaop的最基本配置,没有任何参数,有参数的也就在环绕通知@Around
中使用了ProceedingJoinPoint
作为参数,要是切面所通知的方法确实有参数该怎么办?下面通过一个需求来实现aop处理参数的功能。
需求
一个马戏团里有很多演员,编号分别为A、B、C…,老板要记录每个演员的演出次数作为年底发红包的依据。
如果我们让演员去记录自己的演出次数,是可以的,但是你防不了一些歪心眼的演员故意提高自己的演出次数或者有时候演出太着急就会漏记次数。所以这里我们可以让老板聘请一位专门记录演员演出次数的“记录员”这样就绝对不会出错了。
接下来我们用springAOP来实现这一需求,同样,本文给出两种写法注解式和xml配置的方式。
注解
重写接口
接上文,我们在Performance
里添加一个方法plackTrack(String number)
代码如下
package com.springinaction.service;public interface Performance { public void perform(); public void plackTrack(String number);}
注意,这里包含参数number
为演员的编号。
实现接口
这里依然使用Actor
来实现接口,如下
package com.springinaction.service;import org.springframework.stereotype.Component;@Componentpublic class Actor implements Performance { @Override public void perform() { System.out.println("表演中..."); } @Override public void plackTrack(String number) { System.out.println(number + " number actor"); }}
编写参数切面
package com.springinaction.aop;import java.util.HashMap;import java.util.Map;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.stereotype.Component;@Aspect@Componentpublic class TrackCountAnnotation { private Map<String,Integer> trackCounts = new HashMap<String,Integer>(); @Pointcut("execution(** com.springinaction.service.Performance.plackTrack(String)) && args(trackNumber)") public void trackPlayed(String trackNumber){} @Before("trackPlayed(trackNumber)") public void countTrack(String trackNumber){ System.out.println("i am record..." + trackNumber + " people"); int currentCount = getPlayCount(trackNumber); trackCounts.put(trackNumber, ++currentCount); } public int getPlayCount(String trackNumber) { return trackCounts.get(trackNumber)!=null?trackCounts.get(trackNumber):0; }}
这里注意切点表达式,
比普通的aop多了参数的类型和参数名,这里定义了Map<String,Integer>
来存演员的编号和对应的演出次数,这边就只加了一个@Before
的注解,意思就是演员在演出之前将其次数加一,没有对演出失败或者其他意外的情况做处理,可以使用@AfterReturning
和 @AfterThrowing
处理。
编写测试类
package com.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.springinaction.aop.TrackCountAnnotation;import com.springinaction.service.Actor;public class ShowTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop-annotation.xml"); Actor actor = (Actor)context.getBean("actor"); TrackCountAnnotation tc = (TrackCountAnnotation) context.getBean("trackCountAnnotation"); actor.plackTrack("A"); actor.plackTrack("B"); actor.plackTrack("B"); actor.plackTrack("C"); actor.plackTrack("C"); actor.plackTrack("C"); actor.plackTrack("D"); actor.plackTrack("D"); System.out.println("A------> " + tc.getPlayCount("A")); System.out.println("B------> " + tc.getPlayCount("B")); System.out.println("C------> " + tc.getPlayCount("C")); System.out.println("D------> " + tc.getPlayCount("D")); System.out.println("E------> " + tc.getPlayCount("E")); System.out.println("F------> " + tc.getPlayCount("F")); System.out.println("G------> " + tc.getPlayCount("G")); }}
输出为
i am record...A peopleA number actori am record...B peopleB number actori am record...B peopleB number actori am record...C peopleC number actori am record...C peopleC number actori am record...C peopleC number actori am record...D peopleD number actori am record...D peopleD number actorA------> 1B------> 2C------> 3D------> 2E------> 0F------> 0G------> 0
这样就通过注解的方式来实现开头的需求,下面是xml配置。
XML配置
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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> <bean id="oldClown" class="com.springinaction.service.OldClown" /> <bean id="trackCountXml" class="com.springinaction.aop.TrackCountXml" /> <aop:aspectj-autoproxy proxy-target-class="true" /> <aop:config> <aop:aspect id="aspect" ref="trackCountXml"> <aop:pointcut expression="execution(** com.springinaction.service.Performance.plackTrack(String)) and args(trackNumber)" id="trackPlayed" /> <aop:before method="countTrack" pointcut-ref="trackPlayed" /> </aop:aspect> </aop:config></beans>
这里需注意xml文件中切点表达式的写法,&&
要使用and
代替。
编写参数切面
package com.springinaction.aop;import java.util.HashMap;import java.util.Map;public class TrackCountXml { private Map<String,Integer> trackCounts = new HashMap<String,Integer>(); public void trackPlayed(String trackNumber){} public void countTrack(String trackNumber){ System.out.println("i am record..." + trackNumber + " people"); int currentCount = getPlayCount(trackNumber); trackCounts.put(trackNumber, ++currentCount); } public int getPlayCount(String trackNumber) { return trackCounts.get(trackNumber)!=null?trackCounts.get(trackNumber):0; }}
编写测试类
package com.test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.springinaction.aop.TrackCountXml;import com.springinaction.service.OldClown;public class ShowTestXml { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop-arg-xml.xml");// OldClown oldClown = (OldClown)context.getBean("oldClown");// TODO// // http://www.cnblogs.com/liuling/p/2014-8-23-001.html// oldClown.perform(); OldClown oldClown = (OldClown)context.getBean("oldClown"); TrackCountXml tc = (TrackCountXml) context.getBean("trackCountXml"); oldClown.plackTrack("A"); oldClown.plackTrack("B"); oldClown.plackTrack("B"); oldClown.plackTrack("C"); oldClown.plackTrack("C"); oldClown.plackTrack("C"); oldClown.plackTrack("D"); oldClown.plackTrack("D"); System.out.println("A------> " + tc.getPlayCount("A")); System.out.println("B------> " + tc.getPlayCount("B")); System.out.println("C------> " + tc.getPlayCount("C")); System.out.println("D------> " + tc.getPlayCount("D")); System.out.println("E------> " + tc.getPlayCount("E")); System.out.println("F------> " + tc.getPlayCount("F")); System.out.println("G------> " + tc.getPlayCount("G")); }}
输出的结果和上面是一样的。
因为项目很小就没有放到Git上托管,下面将文件下载地址。
- SpringAOP 处理通知中的参数(注解与xml配置)
- SpringAOP处理通知中的参数
- SpringAOP切点配置(注解与xml配置)
- springAOP中的各种通知
- springAOP基于xml的配置前后环绕通知
- springAop基于注解配置
- SpringAOP入门学习一:基于注解配置切面( AspectJ)
- SpringAOP 通知(adivce)- methodIntercepor
- Spring学习笔记四(AOP中的通知参数和注解开发)
- Hibernate注解配置与XML配置区别
- SpringAOP的五种通知的配置及使用
- Spring AOP 处理通知中的参数【Spring 入门】
- Spring4深入理解AOP02----AOP简介,AspectJ,AOP基于注解和XML配置(5种通知,切面优先级)
- springAOP进行自定义注解,用于方法的处理
- SpringAOP:环绕通知Around
- springAOP的各种通知
- springAOP配置
- SpringAOP配置
- windows下配置JDK环境变量,java -version版本却不改变解决办法?
- 06 Contarner Orchestration
- iOS10 UILabel和UIButton显示不全的解决方案
- 我的我的JAVA世界
- 07 Unikernels
- SpringAOP 处理通知中的参数(注解与xml配置)
- 08 Microservices
- Hadoop的基本使用(2)——通过代码操作HDFS
- pdfmake运用笔记
- linux 增加用户(default)并修改密码
- ANR分析
- Talloc内存池使用教程——(4)使用析构函数
- JavaSE_网络编程_URL类
- php __FILE__ __DIR__魔术常量的使用【PHP进阶教程】