最近在为了看spring的AOP(面向切面编程),在网上查了下,实现它的基本原理是利用动态代理的设计模式,好吧,那就看代理模式是怎么一回事咯。
首先说一下我觉得代理模式的作用就是降低代码的耦合性,减少类与类之间的依赖性。当你为一个类添加方法时,不必去类中去修改方法,只需要生成一个代理(就好比工厂与销售商的关系吧),其实就是当你想在一个方法执行前后插入一些代码,但是又不能去别人的类里面直接改动,于是就出现了代理模式。用网上的话就是你不必去知道被代理对象的具体实现,你只需要生成代理,用代理的方式来修改其中的方法,代理模式最主要的应用就是在spring中的AOP中。那么现在说下代理模式的实现吧。
1、所谓的静态代理
刚看到这个非常容易明白,因为平常经常用咯。
首先写一个接口,代理类和被代理类都得实现的接口
package nc.temptation.test.testProxy;
interface doSomething {
abstract void send();
abstract void post();
}
然后是被代理类咯
package nc.temptation.test.testProxy;
public class People implements doSomething {
@Override
public void send() {
System.out.println("我在发邮件呢!!!");
}
@Override
public void post() {
System.out.println("我在寄东西么!!!");
}
}
最后就是代理类啦
package nc.temptation.test.testProxy;
public class PeopleProxy implements doSomething {
private People people;
public PeopleProxy(People people) {
this.people = people;
}
@Override
public void send() {
System.out.println("-------执行方法之前");
this.people.send();
System.out.println("-------执行方法以后");
}
@Override
public void post() {
System.out.println("-------执行方法之前");
this.people.post();
System.out.println("-------执行方法以后");
}
}
最后来写个测试类
package nc.temptation.test.testProxy;
public class testClient {
public static void main(String[] args) {
People people =new People();
PeopleProxy peopleProxy = new PeopleProxy(people);
peopleProxy.send();
peopleProxy.post();
}
}
最后conlose输出的结果是
-------执行方法之前
我在发邮件呢!!!
-------执行方法以后
-------执行方法之前
我在寄东西么!!!
-------执行方法以后
Process finished with exit code 0
这样一个静态代理的实现就这样写好了,当然,在这中间我们也可以看出来其中的不足,当接口中添加方法时,我们就的同时对代理类与被代理类进行修改,这是非常麻烦的,于是就有了动态代理了
2、懵懂的动态代理
动态代理的实现主要依赖一个接口(InvocationHandler),一个类中的一个方法(Proxy.newProxyInstance)
接口与被代理类都相同
代理类
package nc.temptation.test.testProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyPeople implements InvocationHandler {
//被代理对象
private Object object;
//代理类的构造函数,将被代理对象传入
public ProxyPeople(Object object) {
this.object = object;
}
/**
* invocationHandle必须实现的接口方法
* @param proxy 被代理对象
* @param method 被代理类实现的接口方法
* @param args
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//在执行方法之前插入的方法
System.out.println("-------befert");
//执行被代理对象的方法
Object result = method.invoke(object, args);
//在执行方法后执行的方法
System.out.println("-------last");
return result;
}
/**
* 获取代理对象
* @return
*/
public Object getProxy() {
//当前代理类的线程
ClassLoader loader = Thread.currentThread().getContextClassLoader();
//被代理类实现的接口方法
Class<?>[] intager = object.getClass().getInterfaces();
return Proxy.newProxyInstance(loader,intager,this);
}
}
测试
package nc.temptation.test.testProxy;
public class testClient {
public static void main(String[] args) {
doSomething peopleSend = new People();
ProxyPeople proxyPeople = new ProxyPeople(peopleSend);
doSomething peo = (doSomething) proxyPeople.getProxy();
peo.send();
peo.post();
}
}
输出结果
——-befert
我在发邮件呢!!!
——-last
——-befert
我在寄东西么!!!
——-last
Process finished with exit code 0