AOP也称面向切面编程,是Spring框架的特色之一,经常用来作为java web项目的事务控制、日志处理。在Spring中,AOP是利用java动态代理特性实现的。要说动态代理首先要说设计模式中的代理模式。
1.代理模式类图
2.静态代理实现代理模式
public interface Subject {
public void doSomething();
}
public class RealSubject implements Subject {
@Override
public void doSomething() {
System.out.println("doSomething....");
}
}
public class ProxySubject implements Subject{
private RealSubject realSubject; // 目标类
public ProxySubject (RealSubject realSubject){
this.realSubject = realSubject;
}
@Override
public void doSomething() {
System.out.println("before do something");
realSubject.doSomething();
System.out.println("after do something");
}
}
测试代码:
public class StaticProxyTest {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
ProxySubject staticProxy = new ProxySubject(realSubject);
staticProxy.doSomething();
}
}
3.动态代理实现代理模式
Subject类和RealSubject类同上
public class DynamicProxy implements InvocationHandler {
// 代理的真实对象
private Object subject;
public DynamicProxy(Object subject){
this.subject = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 在代理真实对象前我们可以添加一些自己的操作
System.out.println("before do something");
System.out.println("Method:" + method);
// 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
method.invoke(subject, args);
// 在代理真实对象后我们也可以添加一些自己的操作
System.out.println("after do something");
return null;
}
}
测试代码:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* Created by andrewgyq on 2015/2/9.
*/
public class DynamicProxyTest {
public static void main(String[] args) {
// 代理的真实对象
Subject realSubject = new RealSubject();
// 我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的
InvocationHandler handler = new DynamicProxy(realSubject);
/*
* 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数
* 第一个参数handler.getClass().getClassLoader() ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象
* 第二个参数realSubject.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了
* 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上
*/
Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject
.getClass().getInterfaces(), handler);
System.out.println("代理类名称:" + subject.getClass().getName()); // $Proxy0
System.out.println("代理类名称:" + subject.getClass().getName() + "的父类:" + subject.getClass().getSuperclass().getName());
subject.doSomething();
}
}