@Aspect public class TrackCounter { private Map<Integer,Integer> trackCounts=new HashMap<Integer, Integer>(); //@Pointcut("execution(* com.service.CompactDisc.playTrack(int)) && args(trackNumber)") //带入输入参数 //@Pointcut("target(com.service.CompactDisc) && args(trackNumber)") // target 匹配目标对象(非AOP对象)为指定类型 //@Pointcut("within(com.service..*) && args(trackNumber)") //com.service 包以及子包下的所有方法都执行 //@Pointcut("within(com.service..CompactDisc+) && args(trackNumber)") //com.service 包的CompactDisc类型以及子类型 @Pointcut("this(com.service.CompactDisc) && args(trackNumber)") //匹配当前AOP代理对象类型,必须是类型全称,不支持通配符 public void trackPlayed(int trackNumber){} @Before("trackPlayed(trackNumber)") public void countTrack(int trackNumber){ int playCount = getPlayCount(trackNumber); trackCounts.put(trackNumber,playCount+1); System.out.println(trackCounts.toString()); } public int getPlayCount(int trackNumber){ return trackCounts.containsKey(trackNumber) ? trackCounts.get(trackNumber) : 0; } }
View Code 5、利用切面注入新功能Java并不是动态语言。一旦类编译完成了,我们就很难为该类添加新的功能了。但是,我们的切面编程却可以做到动态的添加方法...话虽如此,其实也不过是障眼法罢了。实际上,面向切面编程,不过是把方法添加到切面代理中,当要对添加的方法调用的时候,可以把被通知的 Bean 转换成相应的接口。也就是代理会把此调用委托给实现了新接口的某个其他对象。实际上,一个bean的实现被拆分到了多个类中。(说实话,想了半天,实在想不到这个功能有什么作用......)
(1) 重新定义一个接口和实现类
public interface Encoreable { void performEncode(); }
View Code
public class DefaultEncoreable implements Encoreable { public void performEncode() { System.out.println("this is DefaultEncoreable"); } }
View Code(2) 把接口实现类嵌入到目标类代理中
@Aspect public class EncoreableIntroducer { @DeclareParents(value = "com.service.CompactDisc+", defaultImpl = DefaultEncoreable.class) //value 表示要嵌入哪些目标类的代理 。 defaultImpl:表示要嵌入的接口的默认实现方法 public static Encoreable encoreable; } View Code
(3) JUnit 测试