7.现在,说说AOP。
首先,什么是AOP,别被这个缩写给唬住了。说白了就是:把和业务逻辑无关的这些逻辑抽取出来的编程方法。这就是AOP。(比如说,日志。这个操作和业务逻辑没有太大的关系,可有可无的操作嘛,因此我们就将它和业务逻辑分离开来)。
(Spring技术手册,上的解释是:在一个服务流程中插入与业务逻辑无关的系统服务逻辑这样的逻辑称为Cross-cutting concerns ,将Cross-cutting concerns 独立出来设计为一个对象,这样的对象称之为Aspect ,Aspect-oriented programming 着重在Aspect的设计及应用程序的织入)
Spring通过多种方式实现AOP,这里来讨论一下代理(Proxy)机制。
Spring代理机制,分为静态代理和动态代理。分别讨论一下:
● 实现静态代理时,代理对象与被代理的对象必须实现同一接口。然后,写很多实现代理的代码,因此业务逻辑被湮没在与业务无关的逻辑这中,所以这种代理没有什么可用性。(我认为!)
● 在JDK1.3之后加入开发动态代理的API。使用动态代理,可以使一个操作对应于多个被代理的对象。操作处理类,必须实现java.lang.reflect.InvocationHandler接口。同时必须定义所要代理的接口。
代码片段:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.*;
import java.util.logging.*;
public class LogHandler implements InvocationHandler ...{
private Logger logger = Logger.getLogger(this.getClass().getName());
private Object isBind;
public Object bind(Object obj)...{
this.isBind = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable ...{
Object result = null;
try...{
logger.log(Level.INFO, "mehtod starts..." + method);
result = method.invoke(isBind,args);
logger.log(Level.INFO, "mehtod ends..." + method);
}catch(Exception e )...{
logger.log(Level.INFO, "fail..." + method);
}
return result;
}
}
接口代码片段:
public interface IAOP ...{
public void hello(String username);
}
接着,让业务逻辑实现该接口。
最后,编写一个实现类,来看看效果:
public class HelloAOPDemo ...{
public static void main(String args[])...{
LogHandler logHandler = new LogHandler();
IAOP helloAOP = (IAOP) logHandler.bind(new HelloAOP());
helloAOP.hello("sunyadong");
}
}
上述方式,是Spring 中实现 AOP的一种方式。Spring可以用其他方式把Aspect加到业务逻辑中,也就织入(Weave)。 现在不得不说几个Spring AOP的术语。
Aspect
将业务逻辑中的如日志操作等这类操作,集合起来设计成可独立应用的对象。这些对象就是Aspect。
Advice
Aspect的具体实现就是Advice,将上面的LogHandler类就是Advice实例。
Pointcut
被织入的具体位置就是Pointcut。
还有Joinpoint、Target等其它的术语。我理解大体就是把Advice在Pointcout上织入到程序中与业务逻辑一起工作。
不同的AOP框架会有不同的AOP实现,主要差别在于Jointpoint 、Aspect 的丰富程度,以及它们如何被织入至应用程序。 Spring的Advice用java编写,定义pointcut可以使用XML,并且实现了AOP Alliance的规范接口。