代理模式,顾名思义就是让别人帮你做一些事情。因为有的事情你自己可能做起来不是很方便,比如买房子要办理各种各样的手续。那说明客户本身和代理本身都具有一些操作目标方法,只是代理类更好操作一点。下面看代码实现
静态代理
定义一个房子接口,具有买房的功能
/**
* 房子有买的功能
*/
public interface House {
void buyHouse();
}
定义一个客户类,实现房子
public class Customer implements House {
@Override
public void buyHouse() {
System.out.println("我是客户我要想买一套房子");
}
}
定义一个代理类,帮助客户买房
/**
* 中介类
*/
public class ProxyCustomer implements House {
private House house;
public ProxyCustomer(House house){
this.house=house;
}
@Override
public void buyHouse() {
before();
//调用原方法
house.buyHouse();
after();
}
public void before() {
System.out.println("买房之前中介帮你办理手续");
}
public void after() {
System.out.println("买房之后中介帮你产生售后服务");
}
}
测试
public class MainTest {
public static void main(String[] args) {
House customer=new Customer();
House house = new ProxyCustomer(customer);
house.buyHouse();
}
}
结果
买房之前中介帮你办理手续
我是客户我要想买一套房子
买房之后中介帮你产生售后服务
静态代理虽然满足设计模式里面的开闭原则,但是如果我们在实际的开发中。比如spring里面事务的增强就是用到了代理模式。如果采用静态代理模式,那么我有多少个service类就要写多少个事务代理对象,这样显然是不好的。那为了解决这个问题,我们一般会用到jdk里面的动态代理模式。
jdk代理
jdk代理主要是通过生成接口的实现类实现的代理
/**
* 目标对象,房子,拥有一个买房的方法
*/
public interface House {
void buyHouse();
}
/**
* 实现客户端类
*/
public class Customer implements House {
@Override
public void buyHouse() {
System.out.println("买套房子玩玩。。。。。。。。。。");
}
}
/**
* jdk代理对象生成类
*/
public class JDKProxy implements InvocationHandler {
private House house;
public JDKProxy(House house) {
this.house=house;
}
/**
* 获取代理对象的方法,实际上就是通过类加载器,以及类实现的接口,生成接口的实现类
* @param <T>
* @return
*/
public <T> T getProxy() {
return (T) Proxy.newProxyInstance(house.getClass().getClassLoader(), house.getClass().getInterfaces(), this);
}
/**
*通过代理类调用的时候,就会反射调用此方法。代理前,代理后的处理
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("办点手续");
Object result = method.invoke(house, args);
System.out.println("搞点服务");
return result;
}
public class MainTest {
public static void main(String[] args) {
Customer customer = new Customer();
JDKProxy jdkProxy = new JDKProxy(customer);
House customerProxy = jdkProxy.getProxy();
customerProxy.buyHouse();
}
}
结果
办点手续
买套房子玩玩。。。。。。。。。。
搞点服务
CGLIB代理
cglib代理主要是通过生成子类进行代理
/**
* 目标对象,房子,拥有一个买房的方法
*/
public interface House {
void buyHouse();
}
/**
* 实现客户端类
*/
public class Customer implements House {
@Override
public void buyHouse() {
System.out.println("买个10栋房子。。。");
}
}
结果
办点手续
买套房子玩玩。。。。。。。。。。
搞点服务
/**
* Cglib代理生成对象,实现MethodInterceptor接口
*/
public class CglibProxy implements MethodInterceptor {
private Object target;
/**
* 通过Enhancer创建一个子类进行代理。
* @param target
* @return
*/
public Object getInstance(Object target)
{
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
//调用回调callback,会进入到intercept方法进行拦截,进而被代理
enhancer.setCallback(this);
Object obj = enhancer.create();
return obj;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("办理点手续");
Object object = methodProxy.invokeSuper(o, objects);
System.out.println("搞点服务");
return object;
}
}
public class MainTest {
public static void main(String[] args) {
House customer = new Customer();
CglibProxy cglibProxy = new CglibProxy();
House house = (House)cglibProxy.getInstance(customer);
house.buyHouse();
}
}
结果
办理点手续
买个10栋房子。。。
搞点服务