在学Spring时,又提到了AOP面向切面(Aspects-Oriental-Programming)
其实它的原理就是动态代理,只是Spring帮我们封装起来了
JDK的动态代理主要是用到类:java.lang.reflect中的InvocationHandler接口与Proxy类
实现接口InvocationHandler,实现方法invoke这个方向影射时就有提过了
实现时调用Proxy的newProxyInstance方法进行代理
以用户操作为例,照样画葫芦装一下逼,由于只是装逼,所以没有进model层,怕麻烦。。
首先弄个接口UserDao.java
package com.proxy.dao;
public interface UserDao {
public void delete();
public void save();
public void load();
public void update();
}
然后就是实现接口的UserImplt
package com.proxy.implt;
import com.proxy.dao.UserDao;
public class UserImplt implements UserDao {
@Override
public void delete() {
System.out.println("delete!!");
}
@Override
public void save() {
System.out.println("save success!!");
}
@Override
public void load() {
System.out.println("load user");
}
@Override
public void update() {
System.out.println("update success!!!");
}
}
搞个代理工厂Dynamic_proxy_factory,这里就是中心代码了实现了InvocationHandler接口,重写方法Invoke,这里我定义了个重复加载的方法printTime用于打印每个方法执行的时间
</pre><pre name="code" class="java">public class Dynamic_proxy_factory implements InvocationHandler {
private Object target;
public Object getTarget() {
return target;
}
public void setTarget(Object target) {
this.target = target;
}
public static void printTime(Method method){
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
System.out.println("Method run time:" + method.getName() + df.format(new Date()));// new Date()为获取当前系统时间)
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
printTime(method);
method.invoke(target, args);
return null;
}
}
来个Test来测试一下UserTest
import java.lang.reflect.Proxy;
import com.proxy.dao.UserDao;
import com.proxy.factory.Dynamic_proxy_factory;
import com.proxy.implt.UserImplt;
public class UserTest {
/**
* @param args
*/
public static void main(String[] args) {
Test_1();
}
private static void Test_1(){
UserDao userDao = new UserImplt();//原来的业务逻辑
Dynamic_proxy_factory dpf = new Dynamic_proxy_factory();//new 一个代理工厂
dpf.setTarget(userDao);//把原来的逻辑交给代理
UserDao userProxy = (UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), dpf);
<span style="white-space:pre"> </span>//产生一个代理对象
userProxy.delete();
userProxy.save();
userProxy.update();
}
运行结果:
到这里就完成了JDK动态代理的过程,它帮我们减少了重复代码的问题,达成了松偶合,AOP的思想实在。。。。。。还得学习。。。