首先说AOP是一种思想,它和具体的实现技术无关,任何一种符合AOP思想的技术实现,都可以看作是AOP的实现。
JDK1.3之后出现了动态代理的机制,通过这种机制,便可以轻松实现AOP的思想。其实Spring的AOP就是建立在动态代理的机制上的。
(1)原来记录日志的方式
示例:public class TimeBook{
private Logger logger=Logger.getLogger(this.getClass().getName());
//审核数据的相关程序
public void doSomeThing(String name){
logger.log(Level.INFO,name+"开始审核数据");
...........
logger.log(Level.INFO,name+"审核数据结束“);
}
(2)通过面向接口编程实现日志的输出
示例: public interface TimeBookInterface{
public void doSomeThing(String name);
}
public class TimeBook implements TimeBookInterface{
public void doSomeThing(String name){
//审核数据的相关程序
.........................
}
}
//编写一个代理类,用来实现日志的输出,该类针对前面的接口编程,不是针对具体类。
public class TimeBookProxy{
private Logger logger=Logger.getLogger(this.getClass().getName());
private TimeBookInterface timeBookInterface;
//在该类中针对前面的接口进行编程,而不是针对具体的类
//构造方法中,传递接口引用
public TimeBookProxy(TimeBookInterface timeBookInterface){
this.timeBookInterface=timeBookInterface;
]
//实际的业务处理逻辑
public void doSomeThing(String name){
logger.log(Level.INFO,name+"开始审核数据”);
timeBookInterface.doSomeThing(name);
logger.log(Level.INFO, name+"审核数据结束“);
}
}
//测试部分代码
TimeBookProxy timeBookProxy=new TimeBookProxy(new TimeBook());
timeBookProxy.doSomeThing("张三");
(3)使用JAVA的代理机制进行日志的输出
第二种方式尽管有了一定的改进,但是 还是需要实现一定的”接口“,有局限性。
Java的InvocationHandler接口可以实现这种功能,
示例:
//代理类实现接口 InvocationHandler
public class LogProxy implements InvocationHandler{
private Logger logger=Logger.getLogger(this.getClaa().getName());
private Object delegate;
//绑定代理对象
public Object bind(Object delegate){
this.delegate=delegate;
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(),this);
}
//针对接口编程
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
Object result=null;
try{
//在方法调用前后进行日志的输出
logger.log(Level.INFO, args[0]+"开始审核数据”);
result=method.invoke(delegate,args);
logger.log(Level.INFO,args[0]+"审核数据结束");
}
}
}
//定义接口
public Interface TimeBookInterface{
public void doSomeThing(String name);
}
//编写实现类,实现自己的业务逻辑
public class TimeBook implements TimeBookInterface{
public void doSomeThing(String name){
//审核数据的相关程序
..............................
}
}
//测试代码
LogProxy logproxy=new LogProxy();
TimeBookInterface timeBookProxy=(TimeBookInterface)logproxy.bind(new TimeBook());
timeBoookeProxy.doSomeThing("张三");
-------------------------------------------------------------------------------------------------------------------------------------
对以上三种方式进行总结:
1 第一种方式,需要在每个类中“都”增加,对输出日志信息的代码
2 第二种方式,虽然实现了业务逻辑与输出日志信息代码的分离,但是 还是需要实现固定的接口
3 第三种方式,正真实现了对,输出日志信息的代码的重用,并且不依赖于固定的接口实现。