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

172 阅读2分钟

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

定义aspect

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被执行的次数。

定义配置

@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

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

@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”或扫描下方二维码关注微信公众号,第一时间获取最新文章(^_^)

谈谈IT