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

在上一篇文章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
29
@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));
}
}

© 2022 谈谈IT All Rights Reserved. 本站访客数人次 本站总访问量
Theme by hiero