AOP背景
Dijkstra--separation of concerns(分散关注)
所谓的分离关注就是将某一通用的需求功能从不相关的类之中分离出来;同时,能够使得很多类共享一个行为,一旦行为发生变化,不必修改很多类,只要修改这个行为就可以。
设计模式孜孜不倦追求的是调用者和被调用者之间的解耦。
OOP-面向对象编程
针对问题领域中以及业务处理过程中存在的实体及其属性和操作进行抽象和封装。
面向对象的核心概念是纵向结构的,其目的是获得更加清晰高效的逻辑单元划分。
AOP:Aspect oriented programming. AOP实际是设计模式的一种扩展,提供从另一个角度来考虑程序结构以完善面向对象编程(OOP)。
面向对象将应用程序分解成各个层次的对象。
而AOP将程序分解成各个方面或者说关注点这使得可以模块化诸如事务管理等这些横切多个对象的关注点。(这些关注点术语称作横切关注点。)
AOP的核心思想就是将应用程序中的业务逻辑处理部分同对其提供支持的通用服务,即所谓的“横切关注点”进行分离,这些“横切关注点”贯穿了程序中的多个纵向模块的需求。
事务
安全
日志……
AOP是一个概念,并没有设定具体语言的实现,它能克服那些只有单继承特性语言的缺点(如Java),目前AOP具体实现有以下几个项目:
AspectJ (TM):创建于Xerox PARC. 有近十年历史,成熟。缺点:过于复杂;破坏封装;需要专门的Java编译器。
动态AOP:使用JDK的动态代理API或字节码Bytecode处理技术。
AOP目的
应用切面
基于JAVA动态代理的AOP实现原理
public class AOPHandler implements InvocationHandler {
private List interceptors = null;
private Object objOriginal;
public Object bind(Object objOriginal) {
this.objOriginal = objOriginal;
//返回动态代理实例
return Proxy.newProxyInstance(objOriginal.getClass().getClassLoader(), objOriginal.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
Throwable ex = null;
InvocationInfo invInfo = new InvocationInfo(proxy, method, args, objOriginal, ex);
//预执行
invokeInterceptorsBefore(invInfo);
try {
result = method.invoke(objOriginal, args);
invInfo.setResult(result);
//后执行
invokeInterceptorsAfter(invInfo);
} catch (Exception e) {
invInfo.setException(e);
//异常执行
invokeInterceptorsException(invInfo);
}
return result;
}
//加载Interceptor
private synchronized List getInterceptors() {
if(interceptors == null) {
interceptors = new ArrayList();
Properties p = new Properties();
ClassLoader loader = AOPHandler.class.getClassLoader();
try {
p.load(loader.getResourceAsStream("interceptor.properties"));
String interceptorName = p.getProperty("interceptorName");
Class cl = Class.forName(interceptorName);
interceptors.add(cl.getConstructor(new Class[]{}).newInstance(new Object[]{}));
} catch (Exception e) {
e.printStackTrace();
}
}
return interceptors;
}
private void invokeInterceptorsBefore(InvocationInfo invInfo) {
interceptors = getInterceptors();
int len = interceptors.size();
for(int i=0; i<len; i++) {
((MyInterceptor) interceptors.get(i)).before(invInfo);
}
}
private void invokeInterceptorsAfter(InvocationInfo invInfo) {
interceptors = getInterceptors();
int len = interceptors.size();
for(int i=0; i<len; i++) {
((MyInterceptor) interceptors.get(i)).after(invInfo);
}
}
private void invokeInterceptorsException(InvocationInfo invInfo) {
interceptors = getInterceptors();
int len = interceptors.size();
for(int i=0; i<len; i++) {
((MyInterceptor) interceptors.get(i)).exceptionThrow(invInfo);
}
}
}
interceptor.properties配置文件:
InterceptorName=com.ht.MyInterceptor
拦截信息基本类
public class InvocationInfo {
private Object proxy;
private Method method;
private Object[] args;
private Object result;
private Throwable exception;
public InvocationInfo(Object proxy, Method method, Object[] args, Object result, Throwable exception) {
this.proxy = proxy;
this.method = method;
this.args = args;
this.result = result;
this.exception = exception;
}
public Object getProxy() {
return proxy;
}
public void setProxy(Object proxy) {
this.proxy = proxy;
}
public Method getMethod() {
return method;
}
public void setMethod(Method method) {
this.method = method;
}
public Object[] getArgs() {
return args;
}
public void setArgs(Object[] args) {
this.args = args;
}
public Object getResult() {
return result;
}
public void setResult(Object result) {
this.result = result;
}
public Throwable getException() {
return exception;
}
public void setException(Throwable exception) {
this.exception = exception;
}
}
自定义拦截器接口
public interface Interceptor {
public void before(InvocationInfo invInfo);
public void after(InvocationInfo invInfo);
public void exceptionThrow(InvocationInfo invInfo);
}
具体拦截器实现
public class MyInterceptor implements Interceptor {
@Override
public void before(InvocationInfo invInfo) {
System.out.println("pre processing...");
}
@Override
public void after(InvocationInfo invInfo) {
System.out.println("post processing...");
}
@Override
public void exceptionThrow(InvocationInfo invInfo) {
System.out.println("exception processing...");
}
}
AOP 工厂类建立
public class AOPFactory {
public static Object getProxyInstance(String clName) {
AOPHandler handler = new AOPHandler();
Class c;
Object proxy = null;
try {
c = Class.forName(clName);
proxy = handler.bind(c.newInstance());
} catch (Exception e) {
e.printStackTrace();
}
return proxy;
}
}
执行
HelloWorld proxy = (HelloWorld) AOPFactory.getProxyInstance("com.ht.HelloWorldImpl");
proxy.sayHello();
注:实例proxy与HelloWorldImpl 均实现了统一的HelloWorld接口定义方法,通过建立代理可以方便地将日志,安全等事务进行委托。