毕业论文写作

毕业设计需求

计算机毕业设计中Java反射与动态代理JDK与CGLIB

 标题:计算机毕业设计中Java反射与动态代理(JDK与CGLIB)

价格:0元
类型:毕业设计程序教程
 
 
 
点击上方“蓝字”,关注我们.

 

一、反射

概念:在运行状态中,对于任意的一个类,都能够知道这个类的所有字段和方法,对任意一个对象都能够通过反射机制调用一个类的任意方法

 

实现方法:JVM在第一次加载某个类时会生成一个Class对象,里面记录了这个类的信息

 

链接:类加载机制(留坑)

 

二、动态代理

动态代理的作用:在不改变原代码的基础上增加新的功能,如日志、权限检验等

 

反射在动态代理中的应用:由于知道原类的字段、方法等信息,才可以通过代理类执行被代理类的方法

 

动态代理的实现有两种

 

1、JDK代理

实现方法:通过创建一个代理类,这个代理类继承于一个Proxy类,Proxy类中有一个InvocationHandler接口,这个接口持有被代理对象和一个invoke()方法。创建好代理类对象后,对该对象调用的方法都会交由invoke方法处理。invoke方法接受3个参数:代理对象、方法、参数列表。重写invoke方法便可以在原方法的基础上添加其他逻辑

 

一个JDK代理的简单实现:

 

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy; // 定义一个接口interface MyInterface {    void fun();} // 用一个类去实现这个接口class Person implements MyInterface {    @Override    public void fun() {        System.out.println("Person实现接口方法");    }} // 用一个类实现InvocationHandler接口class MyInvocationHandler<T> implements InvocationHandler {    //InvocationHandler持有的被代理对象    T target;     public MyInvocationHandler(T target) {        this.target = target;    }     /**     * proxy:代表动态代理对象     * method:代表正在执行的方法     * args:代表调用目标方法时传入的实参     */    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("代理执行" + method.getName() + "方法"); // 在原方法的基础上添加其他逻辑        Object result = method.invoke(target, args); // 通过invoke方法调用原方法        return result;    }} public class Main {    public static void main(String[] args) {        Person person = new Person();        InvocationHandler invocationHandler = new MyInvocationHandler<>(person);        MyInterface proxy = (MyInterface) Proxy.newProxyInstance(Person.class.getClassLoader(),                Person.class.getInterfaces(), invocationHandler);        proxy.fun();    }}

 

输出结果:

代理执行fun方法Person实现接口方法

缺陷:只能代理接口方法,因为JDK代理需要继承一个Proxy类,又由于Java的单继承机制,导致代理类无法继承父类的函数,只能实现接口

 

2、CGLIB代理

原理与JDK代理类似,区别在于CGLIB代理创建的代理类直接继承于被代理类,所以可以实现被代理类的方法而非仅仅接口方法

 

一个简单的CGLIB代理实现:

public class Main {    public static void main(String[] args) {        Enhancer enhancer = new Enhancer();        enhancer.setSuperclass(Car.class);        enhancer.setCallback(new MethodInterceptor() {            @Override            public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy)                    throws Throwable {                System.out.println("before");                Object res = methodProxy.invokeSuper(obj, args);                System.out.println("after");                return res;            }        });        Car car = (Car) enhancer.create();        car.print();    }} class Car {    void print() {        System.out.println("执行原方法");    }}

 

由于CGLIB并非JDK自带,所以需要通过Maven引入一个依赖

<dependency>    <groupId>org.sonatype.sisu.inject</groupId>    <artifactId>cglib</artifactId>    <version>3.1.1</version></dependency>

输出结果:

 

before执行原方法after

 

3、JDK代理与CGLIB代理对比

1、JDK代理只能实现接口方法,而CGLIB代理既可以实现接口方法也可以实现类中自带的方法

 

2、性能上,在JDK1.8,CGLIB3.1.1的环境上,每次创建一个代理类并执行同样的方法

 

当执行10000次,JDK代理用时85ms,而CGLIB代理用时190ms,明显JDK代理性能更佳;

 

当执行1000000(一百万)次时,两种代理耗时几乎相等;

 

当执行10000000次时,CGLIB代理已经优于JDK代理。

 

所以在执行次数少时,JDK代理性能更好;反之CGLIB代理性能更好(但是重复执行多于1000000次的任务几乎没有吧...)

————————————————

版权声明:本文为CSDN博主「KKKLxxx」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_45404693/article/details/119972532

 

最新毕业设计成品

版权所有© 帮我毕业网 并保留所有权利

QQ 1370405256 微信 biyebang

QQ:629001810微信:biyebang

收缩