Java静态代理和动态代理总结

静态代理

第一种实现(基于接口):

1》接口

public interface Hello {
    void say(String msg);}

2》目标类,至少实现一个接口

public class HelloImpl implements Hello {    public void say(String msg) {        System.out.println("Hi,"+msg);    }}

3》代理类(与目标类实现相同接口,从而保证功能一致)

public class HelloProxy implements Hello{

private Hello hello;

public HelloProxy(Hello hello){        this.hello = hello;    }

public void say(String msg){        before();        hello.say(msg);        after();    }    private void before(){        System.out.println("Before");    }    private void after(){        System.out.println("After");    }}

3》测试

/** * @Author LZHL * @Create 2017-02-19 10:26 * @Description */public class Main {    public static void main(String[] args) throws Exception {        HelloImpl target = new HelloImpl();        HelloProxy proxy = new HelloProxy(target);        proxy.say("LZHL");    }}

第二种实现(基于目标类):

1>目标类

public class HelloTarget {    public void sayHello(String name){        System.out.println("Hi,"+name);    }}

2>代理类(通过继承目标类,保证功能一致)

public class HelloProxy extends HelloTarget{  private HelloTarget target;  public HelloProxy(HelloTarget target){    this.target = target;  }   @Override    public void sayHello(String name) {        this.before();        target.sayHello(name);        this.after();    }    private void before(){        System.out.println("Before");    }    private void after(){        System.out.println("After");    }}

3>测试

public class Main {    public static void main(String[] args) throws Exception {       HelloTarget target = new HelloTarget();     HelloProxy proxy= new HelloProxy(target);       proxy.sayHello("LZHL");    }}

动态代理

动态代理的代理类是在程序运行期间动态生成的,也有两种实现,一种是JDK动态代理,一种是CGLib动态代理

1》JDK动态代理(基于接口实现,与目标类实现相同接口,从而保证功能一致)

/** * @Author LZHL * @Create 2017-02-19 12:46 * @Description */public class Main {    public static void main(String[] args){

final HelloImpl target = new HelloImpl();

Object proxyInstance = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {            /*             * proxy: 代理对象             * method: 目标对象的方法对象             * args: 目标对象方法的参数             * return: 目标对象方法的返回值             */            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                System.out.println("before");                Object retValue = method.invoke(target, args);                System.out.println("after");                return retValue;            }        });        Hello proxy = (Hello) proxyInstance;        proxy.say("LYX");

//可以把InvocationHandler提取出来,单独写一个类,为了方便大家看,这里我用内部类的形式
        class JDKProxy implements InvocationHandler {            private Object target;            public JDKProxy(Object target){                this.target = target;            }            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {                before();                Object result = method.invoke(target, args);                after();                return result;            }            private void before(){                System.out.println("Before");            }            private void after(){                System.out.println("After");            }        }        InvocationHandler ih = new JDKProxy(target);        Object proxyInstance2 = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), ih);        Hello proxy2 = (Hello) proxyInstance2;        proxy2.say("LZHL");    }}

2》CGLib动态代理(基于目标类,通过继承目标类,从而保证功能一致),需要导入cglib-3.2.4.jar包

pom.xml

<dependencies>    <!-- https://mvnrepository.com/artifact/cglib/cglib -->    <dependency>        <groupId>cglib</groupId>        <artifactId>cglib</artifactId>        <version>3.2.4</version>    </dependency>

</dependencies>

1)目标类

public class Hi {    public void sayHi(String msg){        System.out.println("Hi,"+msg);    }}

2)测试

/** * @Author LZHL * @Create 2017-02-19 13:19 * @Description */public class Main {    public static void main(String[] args) {        Enhancer enhancer = new Enhancer();        //设置父类        enhancer.setSuperclass(Hi.class);        //设置回调函数        enhancer.setCallback(new MethodInterceptor() {            public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {                System.out.println("before");                Object retValue = methodProxy.invokeSuper(target, args);                System.out.println("after");                return retValue;            }        });        Object proxy = enhancer.create();        Hi hi = (Hi) proxy;        hi.sayHi("LXY");

//可以把MethodInterceptor提取出来,单独写一个类,为了方便大家看,这里我用内部类的形式        class CGLibProxy implements MethodInterceptor {

public <T> T getProxy(Class<T> clazz){                return (T) Enhancer.create(clazz, this);            }            public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {                before();                Object result = proxy.invokeSuper(target, args);                after();                return result;            }            private void before(){                System.out.println("Before");            }            private void after(){                System.out.println("After");            }        }

CGLibProxy cgLibProxy = new CGLibProxy();        Hi hi2 = cgLibProxy.getProxy(Hi.class);        hi2.sayHi("LZHL");    }}
				
时间: 2024-08-01 22:43:31

Java静态代理和动态代理总结的相关文章

深入浅出java静态代理和动态代理

首先介绍一下,什么是代理: 代理模式,是常用的设计模式.特征是,代理类与委托类有相同的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类.以及事后处理消息. 代理类和委托类,存在着关联关系.代理类的对象本身并不真正实现服务,知识通过调用委托类的对象的相关方法. 代理类可以分为两种:静态代理和动态代理. 静态代理: 代理类是由程序员创建,或由工具生成的代码 编译成的.在程序运行前,代理类的 *.class文件已经存在了.直接就可以运行 . 动态代理: 动态代理的代理类.没有直接由

【Java】代处理?代理模式 - 静态代理,动态代理

>不用代理 有时候,我希望在一些方法前后都打印一些日志,于是有了如下代码. 这是一个处理float类型加法的方法,我想在调用它前打印一下参数,调用后打印下计算结果.(至于为什么不直接用+号运算,见[Java]Float计算不准确) package com.nicchagil.study.java.demo.No09代理.No01不用代理; import java.math.BigDecimal; public class FloatCalculator { public float add(fl

java静态代理与动态代理简单分析

原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/5860749.html 1.动态代理(Dynamic Proxy) 代理分为静态代理和动态代理,静态代理是在编译时就将接口.实现类.代理类一股脑儿全部手动完成,但如果我们需要很多的代理,每一个都这么手动的去创建实属浪费时间,而且会有大量的重复代码,此时我们就可以采用动态代理,动态代理可以在程序运行期间根据需要动态的创建代理类及其实例,来完成具体的功能. 其实方法直接调用就可以完成功能,为什么

Java基础:静态代理和动态代理

转载请注明出处:jiq?钦's technical Blog 一.静态代理: 假设原来有一个实现了指定接口/抽象类的子类: class RealSubject implements Subject{ public void request(){ System.out.print("real request handling\n"); } } 现在有两种情况会发生: 1新的代码需要调用Subject接口,但是需要给每个接口加入新代码(比如日志记录.权限控制等): 2旧的代码已经使用了Su

【java项目实战】代理模式(Proxy Pattern),静态代理 VS 动态代理

这篇博文,我们主要以类图和代码的形式来对照学习一下静态代理和动态代理.重点解析各自的优缺点. 定义 代理模式(Proxy Pattern)是对象的结构型模式,代理模式给某一个对象提供了一个代理对象,并由代理对象控制对原对象的引用. 代理模式不会改变原来的接口和行为,仅仅是转由代理干某件事,代理能够控制原来的目标,比如:代理商,代理商仅仅会买东西,但并不会改变行为.不会制造东西. 让我们通过以下的代码好好理解一下这句话. 分类 静态代理和动态代理 静态代理 静态代理类图 代码演示样例 接口 pac

Java设计模式学习06——静态代理与动态代理(转)

原地址:http://blog.csdn.net/xu__cg/article/details/52970885 一.代理模式 为某个对象提供一个代理,从而控制这个代理的访问.代理类和委托类具有共同的父类或父接口,这样在任何使用委托类对象的地方都可以使用代理类对象替代.代理类负责请求的预处理.过滤.将请求分配给委托类处理.以及委托类处理完请求的后续处理. 二.代理模式结构 UML类图: 由上图代理模式的结构为: 抽象角色: 真实对象和代理对象的共同接口. 代理角色: 代理对象角色内部含有对真实对

Java:静态代理and动态代理

代理模式是常用的设计模式,其特征是代理类与委托类具有相同的接口,在具体实现上,有静态代理和动态代理之分.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务,也就是说代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 静态代理和动态代理的一个显著区别: 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就

JAVA学习篇--静态代理VS动态代理

本篇博客的由来,之前我们学习大话设计,就了解了代理模式,但为什么还要说呢? 原因: 1,通过DRP这个项目,了解到了动态代理,认识到我们之前一直使用的都是静态代理,那么动态代理又有什么好处呢?它们二者的区别是什么呢? 2,通过学习动态代理了解到动态代理是一种符合AOP设计思想的技术,那么什么又是AOP? 下面是我对它们的理解! 代理Proxy: Proxy代理模式是一种结构型设计模式,主要解决的问题是:在直接访问对象时带来的问题 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对

java 代理模式(静态代理、动态代理、Cglib代理) 转载

Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法 代理模式最大的特点就是代理类和实际业务类实现同一个接口(或继承同一父类),代理对象持有一个实际对象的引用,外部调用时操作的是代理对象,而在代理对象的内部实现中又会去调

java静态代理和动态代理(一)

代理Proxy: Proxy代理模式是一种结构型设计模式,主要解决的问题是:在直接访问对象时带来的问题. 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别.通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从