笔记8 AOP练习2

场景描述:

  一张唱片有好多磁道,假设每个磁道只有一首歌,现在需要记录每首歌的播放次数,然后输出。

  主要业务:歌曲播放

  辅助功能:记录播放次数(切面)

1.创建唱片接口,CompactDiscs.java

1 package soundsystem;
2 
3 public interface CompactDiscs {
4     void playTrack(int number);
5 }

2.创建唱片接口的实现类,BlankDisc.java  里面包含一个方法playTrack(int number),根据传入的磁道编号,播放对应的歌曲。

 1 package soundsystem;
 2 
 3 import java.util.List;
 4 
 5 public class BlankDisc implements CompactDiscs {
 6     private String title;
 7     private String artist;
 8     private List<String> tracks;
 9 
10     public String getTitle() {
11         return title;
12     }
13 
14     public void setTitle(String title) {
15         this.title = title;
16     }
17 
18     public String getArtist() {
19         return artist;
20     }
21 
22     public void setArtist(String artist) {
23         this.artist = artist;
24     }
25 
26     public List<String> getTracks() {
27         return tracks;
28     }
29 
30     public void setTracks(List<String> tracks) {
31         this.tracks = tracks;
32     }
33 
34     @Override
35     public void playTrack(int number) {
36         System.out.println(tracks.get(number - 1));
37     }
38 
39 }

3.创建记录播放次数的类,TrackCounter.java<切面>

 1 package soundsystem;
 2 
 3 import java.util.HashMap;
 4 import java.util.Map;
 5 
 6 import org.aspectj.lang.annotation.Aspect;
 7 import org.aspectj.lang.annotation.Before;
 8 import org.aspectj.lang.annotation.Pointcut;
 9 
10 @Aspect
11 public class TrackCounter {
12     private Map<Integer, Integer> trackCounts = new HashMap<Integer, Integer>();
13 
14     @Pointcut("execution(* soundsystem.CompactDiscs.playTrack(int))" + "&& args(trackNumber)")
15     public void trackPlayed(int trackNumber) {
16     }
17 
18     @Before("trackPlayed(trackNumber)")
19     public void countTrack(int trackNumber) {
20         int currentCount = getPlayCount(trackNumber);
21         trackCounts.put(trackNumber, currentCount + 1);
22     }
23 
24     public int getPlayCount(int trackNumber) {
25         return trackCounts.containsKey(trackNumber) ? trackCounts.get(trackNumber) : 0;
26     }
27 }

这个切面使用@Pointcut注解定义命名的切点,并使用@Before将一个方法声明为前置通知,切点还声明了要提供给通知方法的参数。

 

在切点表达式中的args(trackNumber)限定符。它表明传递给playTrack()方法的int类型参数也会传递到通知中去。参数的名称trackNumber也与切点方法签名中的参数相匹 配。这个参数会传递到通知方法中,这个通知方法是通过@Before注解和命名切点trackPlayed(trackNumber)定义的。切点定义中的参数与切点方法中的参数名称是一样的,这样就完成了从命名切点到 通知方法的参数转移。 

4.创建配置文件,TrackCounterConfig.java   <声明两个Bean>

 1 package soundsystem;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import org.springframework.context.annotation.Bean;
 7 import org.springframework.context.annotation.Configuration;
 8 import org.springframework.context.annotation.EnableAspectJAutoProxy;
 9 
10 @Configuration
11 @EnableAspectJAutoProxy
12 public class TrackCounterConfig {
13     @Bean
14     public CompactDiscs sgtPeppers() {
15         BlankDisc cd = new BlankDisc();
16         cd.setTitle("ABCCCCCCCCCCCCCCC");
17         cd.setArtist("CCCCCCCCCCCCCCAB");
18         List<String> tracks = new ArrayList<String>();
19         tracks.add("11111");
20         tracks.add("222222");
21         tracks.add("3333333");
22         tracks.add("44444444");
23         tracks.add("555555555");
24         cd.setTracks(tracks);
25         return cd;
26     }
27 
28     @Bean
29     public TrackCounter trackCounter() {
30         return new TrackCounter();
31     }
32 }

5.测试,TrackCounterTest.java

 1 package soundsystem;
 2 
 3 import org.junit.Test;
 4 import org.junit.runner.RunWith;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.test.context.ContextConfiguration;
 7 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 8 
 9 @RunWith(SpringJUnit4ClassRunner.class)
10 @ContextConfiguration(classes = soundsystem.TrackCounterConfig.class)
11 public class TrackCounterTest {
12     @Autowired
13     private CompactDiscs cd;
14     @Autowired
15     private TrackCounter counter;
16 
17     @Test
18     public void test() {
19         cd.show();
20         cd.playTrack(1);
21         cd.playTrack(2);
22         cd.playTrack(2);
23         cd.playTrack(3);
24         cd.playTrack(3);
25         cd.playTrack(3);
26         cd.playTrack(4);
27         cd.playTrack(4);
28         cd.playTrack(4);
29         cd.playTrack(5);
30         cd.playTrack(5);
31         for (int i = 1; i < 6; i++) {
32             System.out.println("磁道" + i + "播放了" + counter.getPlayCount(i) + "");
33         }
34     }
35 }

6.结果

 

posted @ 2018-04-19 17:38  雨落忧伤-  阅读(195)  评论(0编辑  收藏  举报