1.先了解代理与装饰器 代理,即使代替实现,可以代替功能,遵循一样的实现规范,代理模式还装饰者模式比较像,但是有也区别 具体看代码 装饰模式:对象功能不够强大,所以装饰对象实现更强大的功能 牛奶接口 public interface Milk{
void print();
} 原味牛奶实现 public class PlainMilk implements Milk{
@Override
public void print() {
System.out.println("牛奶");
}
} 逻辑实现: new PlainMilk().print();
加糖牛奶实现【装饰者模式】 public class SugarMilk implements Milk{ private PlainMilk plainMilk ; public SugarMilk(PlainMilk plainMilk){ this.plainMilk=plainMilk; } public void print(){ System.out.println(“加糖”) System.out.println("牛奶"); } } 逻辑实现:装饰对象..... new SugarMilK().print(); 代理模式:直接持有对象 public class MilKWithSugar implements MilK{
private final MilK milK;
public MilKWithSugar() {
this.milK= new MilK ();
}
@Override
public void print() {
System.out.println("糖");
this.coffee.print();
}
} 逻辑实现: new MilKWithSugar ().print();
如上两种方式还有有非常细微的差别 所谓代理模式: 例如:1,银行卡,支付宝,代替了现金支,2,例如,猪八戒,找高老庄媳妇【高老庄媳妇抽象一下】,高老庄媳妇,和孙悟空,都实现抽象,所以孙悟空幻化高老庄媳妇就是代理3,买火车票不一定到车站,售票点也可以买票,售票点就是代理 2.JDK:动态代理实现基本业务:消费之后,自己去消费从来不记账 interface BuyService { void buy(); } class BuyService Impl implements BuyService { @Override public void buy() { System.out.println("买买买感觉就是爽....."); } } 在买的时候希望知道自己花了多少钱【那么久希望在自己消费前,或者消费后,知道自己花了多少钱】 class MoneyNumInvocationHandler implements InvocationHandler { private final Object target;// 需要被代理的对象 private Double money;//统计消费总数
public MoneyCountInvocationHandler(Object target) { this.target = target; this.money = 0.0; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(target, args);//执行代理对象方法 money += 10.0; System.out.println("恭喜:成功消费:" + money+ "元"); return result; } } 测试代码: public class TestSpringAop{ public static void main(String[] args) { BuyService buyService = new BuyServiceImpl(); //返回一个代理类实例 BuyService = (BuyService ) Proxy.newProxyInstance(TestSpringAop.class.getClassLoader(), new Class[] { BuyService .class }, new MoneyInvocationHandler(buyService )); buyService .buy(); buyService .buy(); } } InvocationHandler 中的invoke 返回代理对象实例
如上JDK动态代理实现了,那么对于我们来说,AOP编程也就简单了 主函数中代码,应该放在IOC容器初始化中,扫描包,去看看哪些个类需要生成代理对象,然后构造代理对象到容器中。
invoke方法消费统计,改成切面逻辑就可以了
|