JDK与CGlib动态代理的实现

应用的原型为

执行者:房屋中介Agency(分为JDKAgency、CGlibAgency)

被代理对象:程序员Programmer

被代理对象的实现接口:租户Tenement(CGlibAgency时不需要实现接口)

Tenement 接口:
package com.suzao.spring.test;

/**
 * Tenement
 * @Description 租户
 * @Param
 * @return
 * @Author mc
 * @Date 2018/12/28 16:44
 */
public interface Tenement {

    /**
     * rentHouse
     * @Description 租房方法
     * @Param []
     * @return
     * @Author mc
     * @Date 2018/12/28 18:51
     */
    void rentHouse();
}
Programmer 实现类
package com.suzao.spring.test;

/**
 * Programmer
 * @Description 程序员
 * @Param
 * @return
 * @Author mc
 * @Date 2018/12/28 18:21
 */
public class Programmer implements Tenement {

    /**
     * rentHouse
     * @Description 租房方法
     * @Param []
     * @return
     * @Author mc
     * @Date 2018/12/28 18:52
     */
    @Override
    public void rentHouse() {
        System.out.println("我是程序员,我在找房子!");
    }
}

JDK动态代理:执行者  JDKAgency 

package com.suzao.spring.test;

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

/**
 * JDKAgency
 * @Description JDK房屋中介
 * @Param
 * @return
 * @Author mc
 * @Date 2018/12/28 18:22
 */
public class JDKAgency implements InvocationHandler{

    //拿到被代理对象的引用
    private Tenement target;

    public Object getTenementProxy(Tenement target){
        this.target = target;
        Class clazz = target.getClass();
        //clazz.getInterfaces() 获取它的接口
        //重新动态生成一个class字节码
        //编译
        return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("JDK房屋中介开始执行。。。");
        System.out.println("----------------------------");
        method.invoke(this.target,args);
        System.out.println("----------------------------");
        System.out.println("JDK房屋中介结束执行。。。");
        return null;
    }
}

CGlib动态代理:执行者  CGlibAgency 

package com.suzao.spring.test;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * CGlibAgency
 * @Description CGlib 租房中介
 * @Param
 * @return
 * @Author mc
 * @Date 2018/12/28 19:11
 */
public class CGlibAgency implements MethodInterceptor{

    public Object getTenmentProxy(Class clazz){

        Enhancer enhancer = new Enhancer();

        //告诉cglib,生成的子类需要继承那个类
        enhancer.setSuperclass(clazz);

        //设置回调
        enhancer.setCallback(this);

        //加载到jvm中,并返回代理对象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("CGlib房屋中介开始执行。。。");
        System.out.println("----------------------------");
        methodProxy.invokeSuper(obj,args);
        System.out.println("----------------------------");
        System.out.println("CGlib房屋中介结束执行。。。");
        return null;
    }
}

代理测试类 TestProxy 

package com.suzao.spring.test;

/**
 * TestProxy
 * @Description 测试代理
 * @Param
 * @return
 * @Author mc
 * @Date 2018/12/28 18:46
 */
public class TestProxy {

    public static void main(String[] args) {

        //java动态代理是利用反射机制生成一个实现被代理对象的接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

        //执行者 JDKAgency
        //被代理对象 Programmer
        //被代理对象实现的接口 Tenement
        Tenement  tenement= (Tenement) new JDKAgency().getTenementProxy(new Programmer());
        tenement.rentHouse();
        System.out.println("\n\n");

        //cglib动态代理利用asm开源包,对被代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
        //执行者 CGlibAgency
        //被代理对象 Programmer
        Programmer  programmer= (Programmer) new CGlibAgency().getTenmentProxy(new Programmer().getClass());
        programmer.rentHouse();
    }
}

执行结果:

JDK房屋中介开始执行。。。
----------------------------
我是程序员,我在找房子!
----------------------------
JDK房屋中介结束执行。。。

CGlib房屋中介开始执行。。。
----------------------------
我是程序员,我在找房子!
----------------------------
CGlib房屋中介结束执行。。。

pom.xml中引用:

<dependency>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-core</artifactId>
                    <version>${org.springframework-version}</version>
                </dependency>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
         <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>

原文地址:https://www.cnblogs.com/benefitworld/p/10192438.html

时间: 2024-11-12 11:57:02

JDK与CGlib动态代理的实现的相关文章

Spring AOP中的JDK和CGLib动态代理哪个效率更高?

一.背景 今天有小伙伴面试的时候被问到:Spring AOP中JDK 和 CGLib动态代理哪个效率更高? 二.基本概念 首先,我们知道Spring AOP的底层实现有两种方式:一种是JDK动态代理,另一种是CGLib的方式. 自Java 1.3以后,Java提供了动态代理技术,允许开发者在运行期创建接口的代理实例,后来这项技术被用到了Spring的很多地方. JDK动态代理主要涉及java.lang.reflect包下边的两个类:Proxy和InvocationHandler.其中,Invoc

Spring框架中的JDK与CGLib动态代理

JDK和CGLib动态代理区别 JDK动态代理:利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类, 在调用具体方法前调用InvokeHandler来处理. CGLib动态代理:利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理. 何时使用JDK和CGLib: 1)如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP. 2)如果目标对象实现了接口,可以强制使用CGLIB实现AOP. 3)如果目标

JDK和cglib动态代理原理

本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Spring源码解析 https://blog.csdn.net/column/details/21851.html 部分代码会放在我的的Github:https://github.com/h2pl/ AOP的基础是Java动态代理,了解和使用两种动态代理能让我们更好地理解 AOP,在讲解AOP之前,让我们先来看看Java动态代理的使用方式以及底层实现原理. 转自https://www.jia

JDK及CGLIB动态代理-AOP4种增强

动态代理 AOP底层实现:有接口自动应用的就是JDK动态代理(1).JDK 在运行时运行时注入本质:在内存中构建出接口的实现类特点:被代理对象,必须有接口 实例: import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args)

Java代理之(jdk静态代理/jdk动态代理/cglib动态代理/aop/aspectj)

一.概念 代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道.如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法.如果公司卖多少钱,代理商也卖多少钱,那么代理商就赚不了钱.所以代理商在调用公司的卖方法后,加上自己的利润然后再把产品卖给客户.而客户部直接跟公司打交道,或者客户根本不知道公司的存在,然而客户最终却买到了产品. 专业点说:代理模式是对象的结构型模式,代码模式给某一个对象提供代理,并由代理对象控制原对象

Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)

一.概念 代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道.如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法.如果公司卖多少钱,代理商也卖多少钱,那么代理商就赚不了钱.所以代理商在调用公司的卖方法后,加上自己的利润然后再把产品卖给客户.而客户部直接跟公司打交道,或者客户根本不知道公司的存在,然而客户最终却买到了产品. 专业点说:代理模式是对象的结构型模式,代码模式给某一个对象提供代理,并由代理对象控制原对象

spring aop原理 JDK动态代理和CGLIB动态代理

Spring的两大特性是IOC和AOPIOC负责将对象动态的注入到容器,从而达到一种需要谁就注入谁,什么时候需要就什么时候注入的效果.理解spring的ioc也很重要.但是今天主要来和大家讲讲aop.AOP 广泛应用于处理一些具有横切性质的系统级服务,AOP 的出现是对 OOP 的良好补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理.日志.缓存等等. AOP实现的关键在于AOP框架自动创建的AOP代理.AOP代理主要分为静态代理和动态代理, 静态代理的代表为AspectJ:动态代理则

Java进阶之 JDK动态代理与Cglib动态代理

一.动态代理概述: 与静态代理对照(关于静态代理的介绍 可以阅读上一篇:JAVA设计模式之 代理模式[Proxy Pattern]), 动态代理类的字节码是在程序运行时由Java反射机制动态生成. 注意: 1.AspectJ是采用编译时生成AOP代理类,具有更好的性能,但是需要使用特定的编译器进行处理 2.Spring AOP采用运行时生成AOP代理类,无需使用特定编译器进行处理,但是性能相对于AspectJ较差 二.JDK动态代理 [对有实现接口的对象做代理] 1.JDK动态代理中 需要了解的

JDK动态代理和CGLIB动态代理

转载自http://www.itzhai.com/java-dong-tai-dai-li-zhi-jdk-dong-tai-dai-li-he-cglib-dong-tai-dai-li-mian-xiang-qie-mian-bian-cheng-aop-yuan-li.html 静态代理 静态代理相对来说比较简单,无非就是聚合+多态: 参考:设计模式笔记 – Proxy 代理模式 (Design Pattern) 动态代理 我们知道,通过使用代理,可以在被代理的类的方法的前后添加一些处理方