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上托管,下面将文件下载地址。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 酷派手机home键失灵怎么办 r11屏碎一半黑屏怎么办 金立手机黑屏打不开怎么办 小米8se自动跳出广告怎么办 小米手机总跳出广告怎么办 小米手机总是出现广告怎么办 红米1s开机黑屏怎么办 红米手机打电话黑屏怎么办 小米4c打游戏卡怎么办 电脑总出现拨号连接怎么办 win10电脑没有拨号连接怎么办 红米手机黑屏了怎么办 小米4s黑屏了怎么办 鼠标的左键失灵怎么办 小米5左键失灵怎么办 小米4左键失灵怎么办 小米5s左键失灵怎么办 单击鼠标左键就会自动删除?怎么办 华为五s开不开机怎么办 荣耀8关不了机怎么办 三星s7左键失灵怎么办 华为mate7死机黑屏了怎么办 小米手机max黑屏打不开怎么办 小米max开不了机怎么办 小米6接听电话声音小怎么办 小米手机接听电话声音小怎么办 小米5听筒声音小怎么办 红米手机不能开机怎么办 小米5x升级失败怎么办 安卓手机打电话黑屏怎么办 来电话就出黑屏怎么办 oppo手机停留在开机界面怎么办 小米4c死机了怎么办 苹果手机拨打电话时黑屏怎么办 华为畅享6黑屏怎么办 手机拨号键盘变小了怎么办 小米5s手机黑屏打不开怎么办 小米5s黑屏只能开关机怎么办 手机拨号键没了怎么办 华为手机桌面拨号图标不见了怎么办 华为手机拨号图标不见了怎么办