2019独角兽企业重金招聘Python工程师标准>>>
今天我就写写代理模式,包括静态代理和动态代理。同时也提出我在写代理模式的时候碰到的问题,即在写静态代理的时候,发现了静态代理模式很像装饰者模式,都是通过实现接口和组合的方式来实现,只是真实接口实现类的存在方式不同,静态代理是在代理类里面直接new 一个接口实现类,而装饰者模式是通过构造函数参数传递到装饰类。
百度了一下,下面的观点我是比较认可的:
装饰模式:以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案;
代理模式:给一个对象提供一个代理对象,并有代理对象来控制对原有对象的引用;
装饰模式应该为所装饰的对象增强功能;代理模式对代理的对象施加控制,并不提供对象本身的增强功能。
两者的key point不一样。一个突出扩展功能,一个突出控制对原有对象的引用。
说了这么多了,该上代码了。
接口:
package com.wangbiao.my.proxy;
/**
* @author wangbiao
* @date and time May 22, 2014 5:40:30 PM
*
*/
public interface User {
public void printName(String name);
}
实现类:
package com.wangbiao.my.proxy;
/**
* @author wangbiao
* @date and time May 22, 2014 5:41:29 PM
*
*/
public class UserImp implements User {
@Override
public void printName(String name) {
System.out.println(name);
}
}
静态代理:
package com.wangbiao.my.proxy;
/**
* @author wangbiao
* @date and time May 22, 2014 11:17:27 PM
*
*/
public class StaticProxy implements User{
private User user = new UserImp();
@Override
public void printName(String name) {
// TODO before invoke method
user.printName(name);
// TODO after invoke method
}
}
装饰者模式:
package com.wangbiao.my.proxy;
/**
* @author wangbiao
* @date and time May 22, 2014 11:17:27 PM
*
*/
public class DecoraterClass implements User{
private User user;
public DecoraterClass() {
// TODO Auto-generated constructor stub
}
public DecoraterClass(User user) {
this.user = user;
}
@Override
public void printName(String name) {
// TODO before invoke method
user.printName(name);
// TODO after invoke method
}
}
动态代理(用的是java jdk6 自带的动态代理),也有其他的实现方式,CGLIB和JAVAASSIST.
对于动态代理,个人认为运用的最经典的地方是AOP。
package com.wangbiao.my.proxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author wangbiao
* @date and time May 22, 2014 5:32:34 PM
*
*/
public class Test {
public static Object getProxyInstance(final Object realObject) throws Exception{
Class clazz = Proxy.getProxyClass(User.class.getClassLoader(), new Class[]{User.class});
Constructor[] cons = clazz.getConstructors();
System.out.println(cons);
System.out.println(cons[0].getName());
Object obj = cons[0].newInstance(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println("begin invoke method");
System.out.println("method name is : "+method.getName());
Object retObj = method.invoke(realObject, args);
System.out.println("end invoke method");
return retObj;
}
});
return obj;
// get the proxy object
/*
Object obj = Proxy.newProxyInstance(User.class.getClassLoader(),
new Class[]{User.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("begin invoke method");
System.out.println("method name is : "+method.getName());
Object retObj = method.invoke(realObject, args);
System.out.println("end invoke method");
return retObj;
}
});
return obj;
*/
}
public static void main(String[] args) throws Exception {
User user = (User) getProxyInstance(new UserImp());
System.out.println(user.getClass().getName());//$Proxy0
user.printName("dynamic proxy study");
}
}