笔记8 AOP练习2
场景描述:
一张唱片有好多磁道,假设每个磁道只有一首歌,现在需要记录每首歌的播放次数,然后输出。
主要业务:歌曲播放
辅助功能:记录播放次数(切面)
1.创建唱片接口,CompactDiscs.java
package soundsystem; public interface CompactDiscs {
void playTrack(int number);
}
2.创建唱片接口的实现类,BlankDisc.java 里面包含一个方法playTrack(int number),根据传入的磁道编号,播放对应的歌曲。
package soundsystem; import java.util.List; public class BlankDisc implements CompactDiscs {
private String title;
private String artist;
private List<String> tracks; public String getTitle() {
return title;
} public void setTitle(String title) {
this.title = title;
} public String getArtist() {
return artist;
} public void setArtist(String artist) {
this.artist = artist;
} public List<String> getTracks() {
return tracks;
} public void setTracks(List<String> tracks) {
this.tracks = tracks;
} @Override
public void playTrack(int number) {
System.out.println(tracks.get(number - ));
} }
3.创建记录播放次数的类,TrackCounter.java<切面>
package soundsystem; 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; @Aspect
public class TrackCounter {
private Map<Integer, Integer> trackCounts = new HashMap<Integer, Integer>(); @Pointcut("execution(* soundsystem.CompactDiscs.playTrack(int))" + "&& args(trackNumber)")
public void trackPlayed(int trackNumber) {
} @Before("trackPlayed(trackNumber)")
public void countTrack(int trackNumber) {
int currentCount = getPlayCount(trackNumber);
trackCounts.put(trackNumber, currentCount + );
} public int getPlayCount(int trackNumber) {
return trackCounts.containsKey(trackNumber) ? trackCounts.get(trackNumber) : ;
}
}
这个切面使用@Pointcut注解定义命名的切点,并使用@Before将一个方法声明为前置通知,切点还声明了要提供给通知方法的参数。
在切点表达式中的args(trackNumber)限定符。它表明传递给playTrack()方法的int类型参数也会传递到通知中去。参数的名称trackNumber也与切点方法签名中的参数相匹 配。这个参数会传递到通知方法中,这个通知方法是通过@Before注解和命名切点trackPlayed(trackNumber)定义的。切点定义中的参数与切点方法中的参数名称是一样的,这样就完成了从命名切点到 通知方法的参数转移。
4.创建配置文件,TrackCounterConfig.java <声明两个Bean>
package soundsystem; import java.util.ArrayList;
import java.util.List; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration
@EnableAspectJAutoProxy
public class TrackCounterConfig {
@Bean
public CompactDiscs sgtPeppers() {
BlankDisc cd = new BlankDisc();
cd.setTitle("ABCCCCCCCCCCCCCCC");
cd.setArtist("CCCCCCCCCCCCCCAB");
List<String> tracks = new ArrayList<String>();
tracks.add("");
tracks.add("");
tracks.add("");
tracks.add("");
tracks.add("");
cd.setTracks(tracks);
return cd;
} @Bean
public TrackCounter trackCounter() {
return new TrackCounter();
}
}
5.测试,TrackCounterTest.java
package soundsystem; import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = soundsystem.TrackCounterConfig.class)
public class TrackCounterTest {
@Autowired
private CompactDiscs cd;
@Autowired
private TrackCounter counter; @Test
public void test() {
cd.show();
cd.playTrack();
cd.playTrack();
cd.playTrack();
cd.playTrack();
cd.playTrack();
cd.playTrack();
cd.playTrack();
cd.playTrack();
cd.playTrack();
cd.playTrack();
cd.playTrack();
for (int i = ; i < ; i++) {
System.out.println("磁道" + i + "播放了" + counter.getPlayCount(i) + "次");
}
}
}
6.结果
笔记8 AOP练习2的更多相关文章
- Spring笔记:AOP基础
Spring笔记:AOP基础 AOP 引入AOP 面向对象的开发过程中,我们对软件开发进行抽象.分割成各个模块或对象.例如,我们对API抽象成三个模块,Controller.Service.Comma ...
- Spring学习笔记之aop动态代理(3)
Spring学习笔记之aop动态代理(3) 1.0 静态代理模式的缺点: 1.在该系统中有多少的dao就的写多少的proxy,麻烦 2.如果目标接口有方法的改动,则proxy也需要改动. Person ...
- 笔记13 AOP中After和AfterReturning的区别
AOP中 @Before @After @AfterThrowing@AfterReturning的执行顺序 public Object invoke(Object proxy, Method met ...
- 笔记9 AOP练习3(通过注解引入新功能 )
切面可以为Spring bean添加新方法. 在Spring中,切面只是实现了它们所包装bean相同接口的 代理.如果除了实现这些接口,代理也能暴露新接口的话,会怎么样 呢?那样的话,切面所通知的be ...
- Spring笔记(三)AOP前篇之动态代理
AOP思想是将程序中的业务代码与服务代码进行分离,在运行时进行结合.比较强调程序的层次结构,是一种面向切面的编程.而在AOP实现的底层主要用到了动态代理,而动态代理又分为JDK动态代理和CGLIB动态 ...
- Spring学习笔记之AOP配置篇(一)
[TOC] 1. 创建并声明一个切面 首先,创建一个类,添加@Component注解使其添加到IoC容器 然后,添加@Aspect注解,使其成为一个切面 最后,在配置文件里面,使用<aop:as ...
- 笔记7 AOP练习<有疑问>
场景描述: 核心业务:举行一场古典音乐会. 周边功能:观众入场,关闭手机.落座,觉得音乐好听时鼓掌,觉都不好听则退票.(切面) 1.编写切点(切点用于准确定位应该在什么地方应用切面的通 知)----即 ...
- 笔记7 AOP
1. 通知(Advice) 切面的工作被称为通知.通知定义了切面是什么以及何时使用.除了描述切面要完成的工作, 通知还解决了何时执行这个工作的问题.它应该应用在某个方法被调 用之前?之后?之前和之 ...
- Spring学习笔记4——AOP
AOP 即 Aspect Oriented Program 面向切面编程 首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能. 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务 ...
- [Spring学习笔记 4 ] AOP 概念原理以及java动态代理
一.Spring IoC容器补充(1) Spring IoC容器,DI(依赖注入): 注入的方式:设值方法注入setter(属性注入)/构造子注入(构造函数传入依赖的对象)/字段注入Field(注解) ...
随机推荐
- 读取.properties的内容1
属性文件方便于项目进行更改,在项目开发中用的也是非常的普遍,在这里就把属性文件的读取通过代码进行一个小结: package com.oyy.test; import java.io.BufferedI ...
- JAVA_SE基础——60.初识Object
java是面向对象的语言,核心思想:找适合 的对象做适合 的事情:方式一:自定义类,然后通过自定义的类创建对象.方式二:sun提供了很多的类给我使用,我们只需要认识这些类,我们就可以通过这些类创建对象 ...
- Golang学习--开篇
最近开始接收一个新项目,是使用Golang写的,需要重新捡起Golang来,于是就有了这个系列博客. Golang的环境配置,我就不说了,让我们直接开始. Golang官网:https://golan ...
- Spring Security 入门(3-11)Spring Security 的使用-自定义登录验证和回调地址
配置文件 security-ns.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmln ...
- leetcode算法: Find Largest Value in Each Tree Row
'''You need to find the largest value in each row of a binary tree.Example:Input: 1 / \ 3 2 / \ \ 5 ...
- Text-文本撤销
#撤销操作 from tkinter import * master = Tk() #打开undo按钮 text=Text(master,width=30,height=5,undo=True) te ...
- https://segmentfault.com/a/1190000004518374#articleHeader3
https://segmentfault.com/a/1190000004518374#articleHeader3 https://segmentfault.com/q/10100000049065 ...
- MyBatis 框架系列之基础初始
1.什么是 MyBatis MyBatis 本是 apache 的一个开源项目 iBatis,后改名为 MyBatis,它 是一个优秀的持久层框架,对 jdbc 的操作数据库的过程进行封装,使开发者只 ...
- 爱奇艺2018春招Java工程师编程题题解
字典序最大子序列 题目描述 对于字符串a和b,如果移除字符串a中的一些字母(可以全部移除,也可以一个都不移除)就能够得到字符串b我们就称b是a的子序列. 例如."heo"是&quo ...
- django 表单过滤与查询
7.1 表的查询 查询 Person.objects.all() Person.objects.all()[:10] 切片操作,获取10个人,不支持负索引,切片可以节约内存 Person.object ...