众所周知,JDK的动态代理模式必须实现接口。
以下面的源码为例:
接口一:
public interface ActionInterface {
void doSelf(String str);
String getType();
}
接口二:
public interface InterruupIntf {
void interrup();
}
实现类:
public class MyselfImpl implements ActionInterface, InterruupIntf {
public String getType() {
String type = "公用部门";
System.out.println(type);
return type;
}
public void doSelf(String str) {
System.out.println("业务实现类: " + str + " !");
}
public void interrup() {
System.out.println("发呆三分钟!");
}
}
动态代理需要反射,
* 必须要实现InvocationHandler接口
* 能够对所有的方法进行代理
public class MyInvocationHandler implements InvocationHandler {
private Object obj;
/**
* 通过构造方法来设置被代理的对象
* @param obj
*/
public MyInvocationHandler(Object obj) {
this.obj = obj;
}
/**
* 动态代理需要反射
*
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("+++++++++++调用业务方法之前做其他事情");
Object returnObject = method.invoke(obj, args);
System.out.println("+++++++++++调用业务方法之前做其他事情");
return returnObject;
}
/**
* 测试函数
* 动态代理对所有的代理类都进行了拦截
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws SecurityException
* @throws IllegalArgumentException
*/
public static void main(String[] args) throws InterruptedException,
IllegalArgumentException, SecurityException,
InstantiationException, IllegalAccessException,
InvocationTargetException, NoSuchMethodException {
//实现业务逻辑的类
MyselfImpl muSelf = new MyselfImpl();
//JDK创建的动态逻辑类,调用上面的构造函数注入
MyInvocationHandler myInvocation = new MyInvocationHandler(muSelf);
/*
Class<?> proxyClass = Proxy.getProxyClass(
MyselfImpl.class.getClassLoader(), MyselfImpl.class.getInterfaces());
//建业务逻辑类的动态代理类
Object proxy = proxyClass.getConstructor(
new Class[] { InvocationHandler.class }).newInstance(
new MyInvocationHandler(new MyselfImpl())); */
//建业务逻辑类的动态代理类
Object proxy = Proxy.newProxyInstance(MyselfImpl.class.getClassLoader(), MyselfImpl.class.getInterfaces(), myInvocation);
//业务类自己调用运行代理对象
ActionInterface testIntf = (ActionInterface) proxy;
testIntf.doSelf("我要做业务了!");
testIntf.getType();
InterruupIntf intIntf = (InterruupIntf) proxy;
intIntf.interrup();
}
}
运行最后一个类的MAIN函数,控制台输出结果如下:
+++++++++++调用业务方法之前做其他事情
业务实现类: 我要做业务了! !
+++++++++++调用业务方法之前做其他事情
+++++++++++调用业务方法之前做其他事情
公用部门
+++++++++++调用业务方法之前做其他事情
+++++++++++调用业务方法之前做其他事情
发呆三分钟!
+++++++++++调用业务方法之前做其他事情
看到结果了。
JDK的动态代理,对MyselfImpl所有方法都进行了拦截,在调用真正的业务类方法之前之后都插入了代码,这就是JDK的动态代理。其实SPRING的AOP思想的基本原理也是这个,但是它写的比较负责,而且比较优秀。