代理设计模式:主要分为两种,静态代理和动态代理两种设计模式。并且还分jdk代理和cglib代理。这次在一个开源的项目中,查看源码的时候遇到了,就想看一看,有很多都是从别人的博客上面摘抄过来的,但是还是想写出来。哈哈哈,真任性,在以后的文章中,其他的设计模式我还会给出来的。。。
1、Subject是委托类和代理类的接口
2、RealSubject是委托类,Proxy是代理类
3、request是公共方法
静态代理没什么说的,一个委托类对应一个代理类,代理类在编译期间就已经完全确定下来
动态代理:代理类是在运行时自动生成,不用自己单独创建一个代理类。动态代理可以对委托的代理方法进行处理,比如添加方法,在之前或之后调用其他方法等等,同时这种设计模式在很多插件或者框架中都有用到,比如spring中面向切面编程就有用到。动态代理分为jdk动态代理和cglib动态代理。
jdk动态代理
1、定义业务逻辑
public interface Service{
//目标方法
public abstract void add();
}
public class UserServiceImplimplements Service {
public void add() {
System.out.println("This is addservice");
}
}
2、利用java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口定义代理类的实现。
class MyInvocatioHandlerimplements InvocationHandler {
private Object target;
public MyInvocatioHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Methodmethod, Object[] args) throws Throwable {
System.out.println("-----before-----");
Object result = method.invoke(target,args);
System.out.println("-----end-----");
return result;
}
}
3、使用动态代理
public class ProxyTest {
public static void main(String[] args) {
Service service = new UserServiceImpl();
MyInvocatioHandler handler = newMyInvocatioHandler(service);
Service serviceProxy = (Subject)Proxy.newProxyInstance(service.getClass().getClassLoader(),service.getClass().getInterfaces(),handler);
serviceProxy.add();
}
}
执行结果:
-----before-----
This is addservice
-----end-----
使用代理模式流程:
1、生成一个实现InvocationHandler(是代理实例的调用,处理程序实现的接口)接口的类
2、重写invoke(Object proxy, Method method,Object[] args)方法;返回Object result =method.invoke(target, args)对象;invoke是在实例上处理方法调用并返回结果。
3、使用Proxy.newProxyInstance()生成一个代理类;其中有三个参数:
Loader:定义代理类的类加载器
Interfaces:代理类要实现的接口列表
H:指派方法调用的调用处理程序
jdk动态代理使用的局限性
通过反射类Proxy
和InvocationHandler
回调接口实现的jdk动态代理,要求委托类必须实现一个接口,但事实上并不是所有类都有接口,对于没有实现接口的类,便无法使用该方方式实现动态代理。
CGLib动态代理:
JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。
具体地址:http://blog.csdn.net/yakoo5/article/details/9099133/
接下来我会学习装饰模式,并且会讲明两者之间的区别
参考:http://www.cnblogs.com/chinajava/p/5880870.html