Spring in Acton 4 读书笔记之使用 AOP 监听函数的参数

字数676 大约花费3分钟

目录

  1. 1. 定义 aspect
  2. 2. 定义配置
  3. 3. 测试 aspect

在上一篇文章 Spring in Action 4 读书笔记之使用标签创建 AOP 中讲解了如何使用标签定义 aspect,本文继续进行这部分内容。如前所述,Spring 的 AOP 都是作用在方法级别,有时候,需要监听函数的参数,本文讲解如何根据不同的参数值,执行不同的行为。比如下面的代码,记录不同参数执行的次数。

定义 aspect

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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.CompactDisc.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 + 1);
}

public int getPlayCount(int trackNumber) {
return trackCounts.containsKey(trackNumber)
}

}

可以看到,这里是有 @Pointcut 标签定义了一个 aspect。除了是有 execution 之外,还使用 args 指定参数为 trackNumber,需要注意的是,args 函数的参数名 trackNumber 需要和被监听的 trackPlayed 函数同名。countTrack 函数使用 @Before 标签,定义了在 trackPlayed 方法执行前做的事。这里访问了 trackPlayed 方法的参数 trackNumber,并且记录了该参数 trackNumber 被执行的次数。

定义配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Configuration
@EnableAspectJAutoProxy
public class TrackCounterConfig {

@Bean
public CompactDisc sgtPeppers() {
BlankDisc cd = new BlankDisc();
cd.setTitle("Sgt. Pepper's Lonely Hearts Club Band");
cd.setArtist("The Beatles");
List<String> tracks = new ArrayList<String>();
tracks.add("Sgt. Pepper's Lonely Hearts Club Band");
tracks.add("With a Little Help from My Friends");
tracks.add("Lucy in the Sky with Diamonds");
tracks.add("Getting Better");
tracks.add("Fixing a Hole");
// ...other tracks omitted for brevity...
cd.setTracks(tracks);
return cd;
}

@Bean
public TrackCounter trackCounter() {
return new TrackCounter();
}
}

使用 @EnableAspectJAutoProxy 标签,标注配置类,表示使用代理监听的目标类。并且使用 @Bean 标签,生成 TrackCounter 这个 aspect 的 bean 以及 CompactDisc 的 bean。

测试 aspect

可以使用下面的例子,验证执行次数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=TrackCounterConfig.class)
public class TrackCounterTest {
@Rule
public final StandardOutputStreamLog log = new StandardOutputStreamLog();
@Autowired
private CompactDisc cd;
@Autowired
private TrackCounter counter;
@Test
public void testTrackCounter() {
cd.playTrack(1);
cd.playTrack(2);
cd.playTrack(3);
cd.playTrack(3);
cd.playTrack(3);
cd.playTrack(3);
cd.playTrack(7);
cd.playTrack(7);
assertEquals(1, counter.getPlayCount(1));
assertEquals(1, counter.getPlayCount(2));
assertEquals(4, counter.getPlayCount(3));
assertEquals(0, counter.getPlayCount(4));
assertEquals(0, counter.getPlayCount(5));
assertEquals(0, counter.getPlayCount(6));
assertEquals(2, counter.getPlayCount(7));
}
}

谈谈 IT的文章均为原创或翻译(翻译会注明外文来源),转载请以链接形式标明本文地址: http://tantanit.com/springinacton4-du-shu-bi-ji-zhi-shi-yong-aop-jian-ting-han-shu-de-can-shu/

谈谈IT

欢迎关注官方微信公众号获取最新原创文章