Spring的动态代理有两种:一是JDK的动态代理;另一个是cglib动态代理(通过修改字节码来实现代理)。
今天主要讨论JDK动态代理的方式。
1 AOP各种的实现
AOP就是面向切面编程,我们可以从几个层面来实现AOP。
在编译器修改源代码,在运行期字节码加载前修改字节码或字节码加载后动态创建代理类的字节码,以下是各种实现机制的比较。
2 AOP的实现机制
本章节将详细介绍AOP有各种实现机制。
2.1 动态代理
Java在JDK1.3后引入的动态代理机制,使我们可以在运行期动态的创建代理类。使用动态代理实现AOP需要有四个角色:被代理的类,被代理类的接 口,织入器,和InvocationHandler,而织入器使用接口反射机制生成一个代理类,然后在这个代理类中织入代码。被代理的类是AOP里所说的 目标,InvocationHandler是切面,它包含了Advice和Pointcut。
public interface MyDao {
String getName();
}
public class MydaoImpl implements MyDao {
@Override
public String getName() {
// TODO Auto-generated method stub
System.out.println("this is my daoimpl");
return "ok";
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyProxy implements InvocationHandler {
Object obj = null;
public MyProxy(Object obj) {
super();
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("this is method before");
Object result = method.invoke(this.obj, args);
System.out.println("this is method after");
return result;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyDao dao = new MydaoImpl();
// 获得被代理类的类加载器,使得JVM能够加载并找到被代理类的内部结构,以及已实现的interface
ClassLoader loader = dao.getClass().getClassLoader();
// 获得被代理类已实现的所有接口interface,使得动态代理类的实例
Class<?>[] interfaces = dao.getClass().getInterfaces();
// 用被代理类的实例创建动态代理类的实例,用于真正调用处理程序
InvocationHandler handler = new MyProxy(dao);
/*
* loader : 被代理类的类加载器 interfaces :被代理类已实现的所有接口,而这些是动态代理类要实现的接口列表 handler
* : 用被代理类的实例创建动态代理类的实例,用于真正调用处理程序
*
* return :返回实现了被代理类所实现的所有接口的Object对象,即动态代理,需要强制转型
*/
// 获得代理的实例
MyDao proxy = (MyDao) Proxy.newProxyInstance(loader, interfaces,
handler);
proxy.getName();
// 打印出该代理实例的名称
System.out.println(proxy.getClass().getName());
}
}