《Spring Recipes》第三章笔记7:Introducing States to Your Beans
问题
有时候,需要向一组对象中添加状态,如果调用次数,最后更新时间等。如果所有的对象拥有相同的父类,可以通过在父类中添加状态属性进行解决。但是如果想在具有不同父类的对象中实现相同的效果,就比较困难。
解决方案
可以为对象introduce一个新的接口,并指定一个实现此接口的、具有操作状态功能的实现类。然后再写另外一个通知来改变状态。
例:
假设需要过跟踪每个对象被调用的次数,由于现有类中,没有属性存放状态,所以需要使用AOP introduce一个。
1、定义Counter接口,并实现。
Counter:
public interface Counter {
public void increase();
public int getCount();
}
CounterImpl:
public class CounterImpl implements Counter {
private int count;
public void increase() {
count++;
}
public int getCount() {
return count;
}
}
2、定义切面将CounterImpl类introduce给需要跟踪状态的对象。
CalculatorIntroduction:
@Aspect
public class CalculatorIntroduction {
... ...
@DeclareParents(value = "com.apress.springrecipes.calculator.*CalculatorImpl",
defaultImpl = CounterImpl.class)
public Counter counter;
}
3、定义切面,在需要跟踪的对象每次调用时,都将counter加一。
需要在表达式后添加&&this(counter)
@Aspect
public class CalculatorIntroduction {
... ...
@After("execution(* com.apress.springrecipes.calculator.*Calculator.*(..))&& this(counter)")
public void increaseCount(Counter counter) {
counter.increase();
}
}
4、调用方式:
...
ArithmeticCalculator arithmeticCalculator =(ArithmeticCalculator) context.getBean("arithmeticCalculator");
arithmeticCalculator.add(1,2);
UnitCalculator unitCalculator = (UnitCalculator) context.getBean("unitCalculator");
unitCalculator.add(1,2);
Counter arithmeticCounter = (Counter) arithmeticCalculator;
System.out.println(arithmeticCounter.getCount());
Counter unitCounter = (Counter) unitCalculator;
System.out.println(unitCounter.getCount());