静态代理和动态代理原理及实现(代码片段)

fantongxue fantongxue     2023-04-13     189

关键词:

@(静态代理(Static Proxy)和动态代理(Dynamic Proxy))

静态代理

静态代理要先抽象出一个接口,并且写一个实现类实现这个接口。

//主业务接口
public interface SomeService 
String first();
String second();
//目标类
public class SomeServiceImpl implements SomeService

    public String first() 
        // TODO Auto-generated method stub
        return "I Love You";
    

    public String second() 
        // TODO Auto-generated method stub
        return "China";
    

然后写静态代理类,要求静态代理类要求目标类共同实现主业务接口 。这里的代理类实现的是把目标类的某些方法的返回值变成大写。

public class SomeServiceProxy implements SomeService
    private SomeService target;
    //提供无参构造器和带参构造器传递方法
    public SomeServiceProxy()
        super();
    
    public SomeServiceProxy(SomeService target) 
        super();
        this.target = target;
    
    public String first() 
        // TODO Auto-generated method stub
        return target.first();//正常输出
    
    public String second() 
        // TODO Auto-generated method stub
        return target.second().toUpperCase();//变大写
    

写一个测试类

public class MyTest 
public static void main(String args[])
    //定义目标对象
    SomeService target=new SomeServiceImpl();
    //定义目标对象的代理对象,把目标对象传进去
    SomeService serviceProxy=new SomeServiceProxy(target);
    String result1=serviceProxy.first();
    String result2=serviceProxy.second();
    System.out.println(result1+","+result2);

执行结果
技术图片
执行了代理类之后,second方法的返回值变成了大写。

jdk动态代理

首先jdk动态代理和静态代理一样,都需要先抽象出来一个接口并实现这个接口。

//主业务接口
public interface SomeService 
String first();
String second();
//目标类
public class SomeServiceImpl implements SomeService
    public String first() 
        // TODO Auto-generated method stub
        return "I Love You";
    
    public String second() 
        // TODO Auto-generated method stub
        return "China";
    

然后写测试类,动态代理在测试类中创建(Proxy类的newProxyInstance方法)

public class MyTest 
public static void main(String args[])
    //定义目标对象
    final SomeService target=new SomeServiceImpl();
    //定义目标对象的代理对象
    SomeService serviceProxy=(SomeService)Proxy.newProxyInstance(
            target.getClass().getClassLoader(),//第一个参数:目标类的类加载器
            target.getClass().getInterfaces(),//第二个参数:目标类所实现的所有接口
            new InvocationHandler()        //第三个参数:内部匿名类
                /**
                 * 增强就在这里完成
                 * proxy:代理对象
                 * method:目标方法
                 * args:目标方法的参数列表
                 */
                public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable 
                    // 内部类使用外部类的成员变量,外部类的成员变量必须声明为final类型,否则报错
                    Object result = method.invoke(target, args);
                    //指定操作的是哪个方法
                    if ("second".equals(method.getName())) 
                        result = ((String) result).toUpperCase();
                    
                    return result;
                
            );
    String result1=serviceProxy.first();
    String result2=serviceProxy.second();
    System.out.println(result1+","+result2);

执行结果
技术图片
second方法的返回值也变成了大写。

CGLIB动态代理

使用JDK的Proxy实现代理,要求目标类和代理类实现相同的接口,若目标类不存在接口,则无法使用该方式实现。对于无接口的类,要为其创建动态代理,就要使用CGLIB实现。CGLIB代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代理对象。
所以,使用CGLIB动态代理,要求目标类必须能够被继承,即不能是final的类。

CGLIB是一个外部项目,首先要导入jar包
技术图片

这里不需要抽象一个接口,只写一个主业务类。

//主业务类
public class SomeService 
    public String first() 
        // TODO Auto-generated method stub
        return "I Love You";
    

    public String second() 
        // TODO Auto-generated method stub
        return "China";
    

然后写一个CGLIB动态代理创建工厂

//要实现MethodInterceptor方法,返回的类型是回调函数,所以cglib_ProxyFactory 类本身也为回调函数对象
public class cglib_ProxyFactory implements MethodInterceptor
    private SomeService target;
    public cglib_ProxyFactory() 
        super();
        // TODO Auto-generated constructor stub
    
    public cglib_ProxyFactory(SomeService target) 
        super();
        this.target = target;
    
    //用于创建cglib代理对象
    public SomeService myProxyCreator()
        //增强器
        Enhancer enhancer=new Enhancer();
        //指定父类,即要增强的目标类
        enhancer.setSuperclass(SomeService.class);
        //指定回调函数对象
        enhancer.setCallback(this);
        //创建cglib代理对象
        return (SomeService) enhancer.create();
    
public Object intercept(Object obj, Method method, Object[] args,
        MethodProxy proxy) throws Throwable 
    Object result = method.invoke(target, args);
    if ("second".equals(method.getName())) 
        result = ((String) result).toUpperCase();
    
    return result;

再写一个测试类

public class MyTest 
public static void main(String args[])
    //定义目标对象
    final SomeService target=new SomeService();
    //定义目标对象的代理对象
    SomeService serviceProxy=new cglib_ProxyFactory(target).myProxyCreator();
    String result1=serviceProxy.first();
    String result2=serviceProxy.second();
    System.out.println(result1+","+result2);

执行结果
技术图片
second方法的返回值也变成了大写。

sprigaop原理及源码解析(代码片段)

...  在介绍AOP之前,想必很多人都听说AOP是基于动态代理和反射来实现的,那么在看AOP之前,你需要弄懂什么是动态代理和反射及它们又是如何实现的。想了解JDK的动态代理及反射的实现和源码分析,请参见下面三篇文章JDK... 查看详情

cglib动态代理实现及原理(代码片段)

JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要Cglib了。Cglib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采... 查看详情

cglib动态代理实现及原理(代码片段)

JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要Cglib了。Cglib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采... 查看详情

06设计模式-代理模式(代码片段)

...目标:  》代理模式的应用场景及实现原理  》区分静态代理与动态代理  》cglib和jdkProxy实现动态代理的区别  》手写实现定义的动态代理  》springAop基于动态代理,打下基础5.1.代理模式定义5.1.1.什么是代理模式?... 查看详情

jdk和cglib动态代理原理(代码片段)

...行探究的Java代理介绍Java中代理的实现一般分为三种:JDK静态代理、JDK动态代理以及CGLIB动态代理。在Spring的AOP实现中,主要应用了JDK动态代理以及CGLIB动态代理。但是本文着重介绍JDK动态代理机制,CGLIB动态代理后面会接着探究... 查看详情

代理模式(静态代理,jdk动态代理,jdk动态代理原理分析)(代码片段)

目录代理模式静态代理动态代理动态代理原理分析代理模式静态代理代理类和被代理类在编译期间就已经确定了。packageorg.westos.demo4;/***@authorlwj*@date2020/6/1415:42*/publicinterfaceUserDaovoidadd();voiddelete();voidupdate();voidquery();packageorg.westos. 查看详情

设计模式-动态代理原理及模仿jdkproxy写一个属于自己的动态代理(代码片段)

...大家可以选择性阅读。本篇文章的目的是简单的分析动态代理的原理及模仿JDKProxy手写一个动态代理以及对几种代理做一个总结。对于代理模式的介绍和讲解,网上已经有很多优质的文章,我这里就不会再过多的介绍了,这里推... 查看详情

静态代理和动态代理(代码片段)

...领导的代理。下面将以这个例子来讲解。代理模式又分为静态代理和动态代理。一、静态代理静态代理的使用静态代理,代理类和被代理的类实现了同样的接口,代理类同时持有被代理类的引用,这样,当我们 查看详情

静态代理和动态代理(jdk/cglib)详解(代码片段)

1.静态代理模式代理模式上,基本上有Subject角色,RealSubject角色,Proxy角色。其中:Subject角色负责定义RealSubject和Proxy角色应该实现的接口;RealSubject角色用来真正完成业务服务功能;Proxy角色负责将自身的Request请求,调用realsubjec... 查看详情

springaop实现原理与cglib应用(转)(代码片段)

...的关键就在于AOP框架自动创建的AOP代理,AOP代理则可分为静态代理和动态代理两大类,其中静态代理是指使用AOP框架提供的命令进行编译,从而在编译阶段就可生成AOP代理类,因此也称为编译时增强;而动态代理则在运行时借 查看详情

动态代理(代码片段)

...方法代码动态代理:可以代理任何类优点:我们不需要像静态代理一个类型的类必须跟一个代理,这里可以说是一个工具类,每一个类都可以拿来用,底层利用反射的机制实现,而且静态代理必须和实例实现同一个接口,而有些... 查看详情

代理模式(动态)(代码片段)

目录代理模式(动态)原理特点代码案例优点缺点静态代理和动态代理的区别代理模式(动态)我们知道,静态代理需要自己创建代理对象,如果需要的代理对象比较多的话,代码就会比较繁琐代理类在程序运行时创建的代理方式被成为... 查看详情

spring的静态代理和动态代理(代码片段)

文章目录一、前言二、分类2.1、静态代理2.2、动态代理2.2.1、分类2.2.2、对比三、实现3.1静态代理3.1动态代理3.1.1基于jdk的动态代理3.1.2基于cglib的动态代理四、结语一、前言       开始接触代理是在设计模式动态代理中了解的... 查看详情

静态代理和动态代理(代码片段)

代理模式(静态代理)代理模式是为其他对象提供一种代理以控制对这个对象的访问。定义上也不算好理解,上一个《大话设计模式》的图。Subject类(一般是抽象类或接口),定义了一个方法。RealSubject类实现了这个接口,正常... 查看详情

静态代理和动态代理(代码片段)

代理模式SpringAOP底层就是使用的代理模式。静态代理静态代理角色分析抽象角色:一般使用接口或者抽象类来实现真实角色:被代理的角色代理角色:代理真实角色;代理真实角色后,一般会做一些附属的操作.客户:使用代理角色来进... 查看详情

动态代理+注解+反射实现view的点击事件绑定(代码片段)

...理对象,由代理对象来控制原对象的引用。代理模式分为静态代理和动态代理。静态代理定义接口publicinterfacePlayervoidplay();定义具体的实现类publicclassPlayerImplimplementsPlayer@Overridepublicvoidplay()System.out.println("PlayerImplplay...");定... 查看详情

静态代理,jdk代理和cglib代理的含义及区别(代码片段)

 一:代理模式(静态代理)         代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理。        ... 查看详情

jdk动态代理实现与原理分析(代码片段)

...生产厂家买的,是要通过中间的代理商实现交易。2.静态代理2.1介绍1.代理类是自己手工实现的,自己创建一个java类,表示代理类2.同时也要实现你所要代理的目标3.静态代理的优缺点优点:  1)实现简单  2)容易理解... 查看详情