每天一个设计模式之代理模式

简介: 代理模式介绍静态代理没有什么好说的,不断的写新的类,实现与被代理类一样的接口,从而来拓展功能。缺点太多,如接口变化,就要重写新的代理类。动态代理使用最多的可能就是传说中的aop了。它解决了静态代理的缺点,即使接口变化了,代理类也不需要变化。动态代理实现方式主要有两种:1、jdk自带的 2、cglib技术个人觉得代理模式的用处就是在不对原有类进行修改的情况下,对类的

代理模式介绍

静态代理没有什么好说的,不断的写新的类,实现与被代理类一样的接口,从而来拓展功能。缺点太多,如接口变化,就要重写新的代理类。

动态代理使用最多的可能就是传说中的aop了。它解决了静态代理的缺点,即使接口变化了,代理类也不需要变化。动态代理实现方式主要有两种:1、jdk自带的 2、cglib技术

个人觉得代理模式的用处就是在不对原有类进行修改的情况下,对类的功能进行增强。有前置增强、后置增强、环绕增强、抛出增强、引入增强等。其中前四种增强是对类的方法的增强,叫做织入(Weaving),抛出增强可以对异常进行处理。引入增强是对类进行增强,如给类添加新的方法等。

jdk实现动态代理

接口:

public interface HelloWorld {
  void say();
}

被代理类:

public class Hello implements HelloWorld {

    @Override public void say() {
        System.out.println("Hello World");
    }
}

动态代理类:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JdkDynamicProxy {

private static class HelloWorldDynamicProxy implements  
InvocationHandler{

Object target;

public HelloWorldDynamicProxy(Object target) {

this.target = target;
}

@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Hello Dota");
method.invoke(target, args);
System.out.println("Hello Dota2");
return null;
}

//Object像下转型为T,会有警告,这里利用了泛型,否则调用完的结果还需要强制转换
@SuppressWarnings("unchecked")
public <T> T getProxy(){
return (T)Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}

}

public static void main(String args[]){
Hello hello = new Hello();
HelloWorld proxy = new HelloWorldDynamicProxy(hello).getProxy();
proxy.say();
}
}

结果:

Hello Dota
Hello World
Hello Dota2

Cglib动态代理技术

jdk中的动态代理需要被代理类实现了某个接口。但是cglib可以代理一个没有实现任何接口的类。cglib创建代理的速度比较慢,但是创建代理后运行的速度却非常快,而jdk动态代理却正好相反。还是用上面的例子,cglib的代理类如下。

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

public class CglibDynamicProxy implements MethodInterceptor {

    private static CglibDynamicProxy cglibDynamicProxy = new CglibDynamicProxy();

    public static CglibDynamicProxy getInstance(){
        return cglibDynamicProxy;
    }

    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> cls){
        return (T) Enhancer.create(cls,this);
    }

    @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("dota");
        Object object = methodProxy.invokeSuper(o,objects);
        System.out.println("dota2");
        return object;
    }

    public static void main(String args[]){
    CglibDynamicProxy.getInstance().getProxy(Hello.class).say();
    }

}

另外如果工程用maven管理,使用cglib需要添加maven依赖

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2.2</version>
</dependency>
目录
相关文章
|
4月前
|
设计模式 C#
设计模式之代理模式(Proxy)
设计模式之代理模式(Proxy)
|
5月前
|
设计模式 XML JSON
二十三种设计模式全面解析-代理模式进阶篇:揭秘远程代理
二十三种设计模式全面解析-代理模式进阶篇:揭秘远程代理
|
4月前
|
设计模式
设计模式-代理模式
设计模式-代理模式
|
4月前
|
设计模式 数据安全/隐私保护
设计模式之代理模式
设计模式之代理模式
|
5月前
|
设计模式 缓存
二十三种设计模式全面解析-代理模式(Proxy Pattern)详解:探索隐藏于背后的力量
二十三种设计模式全面解析-代理模式(Proxy Pattern)详解:探索隐藏于背后的力量
|
2月前
|
设计模式 JavaScript Java
设计模式——代理模式
一文讲清楚设计模式中的代理模式
25 0
设计模式——代理模式
|
2月前
|
设计模式 Java 数据库连接
【重温设计模式】代理模式及其Java示例
【重温设计模式】代理模式及其Java示例
24 2
|
14天前
|
设计模式 Go 网络安全
[设计模式 Go实现] 结构型~代理模式
[设计模式 Go实现] 结构型~代理模式
|
1月前
|
设计模式 缓存 Java
23种设计模式,代理模式的概念优缺点以及JAVA代码举例
4月更文挑战第7天】代理模式是一种常用的软件设计模式,它为其他对象提供一种代理以控制对这个对象的访问。这种模式创建具有原始对象相同接口的对象,从而使代理对象在访问者和目标对象之间作为一个中介。
15 0
|
2月前
|
设计模式 uml
设计模式之代理模式
设计模式之代理模式