当前位置: 首页 > news >正文

旅游网站网页设计图片网络营销和网络销售的区别

旅游网站网页设计图片,网络营销和网络销售的区别,oa系统品牌,公司网站建设代理怎么做前言 一般的编译是编译器编译.java文件 生成.class文件 然后JVM加载并运行.class字节码文件 反射的前提是内存中已经有了Class<T>对象 或者 通过Class.forName等方法去加载静态的.class文件 最终还是需要Class对象 那么动态生成Class对象的几种技术 JDK代理 CGL…

前言

一般的编译是编译器编译.java文件  生成.class文件  然后JVM加载并运行.class字节码文件

反射的前提是内存中已经有了Class<T>对象  或者 通过Class.forName等方法去加载静态的.class文件  最终还是需要Class对象

那么动态生成Class对象的几种技术  JDK代理  CGLIB代理  ASM  ByteBuddy Javassist 这几种技术都是内存中生成Class对象 默认都不会有.class静态文件(待确认)  其中JDK代理和CBLIB代理是基于目标接口/父类需要以某种形式被JVM加载(例如已有的.class文件进行代理 或者 目标接口/父类 已经在内存中生成)  然后通过反射调用

反射的前提是需要内存中有Class对象  不管这个Class对象是通过静态加载 或动态加载

JDK、CGLIB、ASM、ByteBuddy、Javassist 最终都可以动态在内存中生成Class对象 利用反射完成功能 

反射是一种操作类,对象,方法的方式   但是内存中已经有了Class对象  不一定非要用反射   也可以直接new 


CGLIB  是基于ASM


ByteBuddy 也是基于ASM   因为JDK代理和CGLIB代理基于目标接口/父类 已经在内存中生成     那么就是ByteBuddy和Javassist  是正在完全动态

JDK 动态代理

目标对象必须实现接口

1.定义接口

public interface UserService {
    void doSomething();
}

目标类

public class UserServiceImpl implements UserService {
    @Override
    public void doSomething() {
        System.out.println("执行核心业务逻辑...");
    }
}
 

以匿名内部类的写法

package com.hrui.jdk;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;/*** @author hrui* @date 2025/4/10 11:03*/
public class JdkProxyDemo {public static void main(String[] args) {UserService target = new UserServiceImpl();UserService proxyInstance = (UserService) Proxy.newProxyInstance(target.getClass().getClassLoader(),       // 类加载器new Class[]{UserService.class},           // 接口列表(proxy, method, args1) -> {System.out.println("before");Object invoke = method.invoke(target, args1);System.out.println("after");return invoke;}//调用处理器 可以以匿名内部类的写法   也可以以单独写一个类实现InvocationHandler接口);proxyInstance.doSomething();}
}

创建代理处理器的写法(InvocationHandler)

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

public class LogInvocationHandler implements InvocationHandler {

    private final Object target;

    public LogInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("方法开始:" + method.getName());
        Object result = method.invoke(target, args); // 反射调用目标方法
        System.out.println("方法结束:" + method.getName());
        return result;
    }
}
 

import java.lang.reflect.Proxy;

public class JdkProxyDemo {
    public static void main(String[] args) {
        // 创建目标对象
        UserService target = new UserServiceImpl();

        // 创建代理对象
        UserService proxyInstance = (UserService) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),       // 类加载器
                new Class[]{UserService.class},           // 接口列表
                new LogInvocationHandler(target)          // 调用处理器
        );

        // 调用方法(会被代理拦截)
        proxyInstance.doSomething();
    }
}
 

可以看到并没有生成静态的.class文件

CGLIB 动态代理

代理对象会继承目标类,不需要目标类实现某接口,目标类不能是final修饰的

引入依赖

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>
 

被代理的目标类

public class UserService {
    public void doSomething() {
        System.out.println("执行业务逻辑");
    }
}
 

创建方法拦截器

package com.hrui.cglib;import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/*** CGLIB 动态代理处理器(基于继承方式实现)* 用于在调用目标类方法前后插入自定义逻辑(如日志记录)** 原理:CGLIB 通过生成目标类的子类,重写方法插入拦截逻辑(类似 AOP)** 注意事项:* - 被代理的类不能是 final 类* - 被代理的方法不能是 final 或 static* - JDK 16+ 需要 JVM 参数开放模块:--add-opens java.base/java.lang=ALL-UNNAMED** 示例用法:*   UserService proxy = (UserService) new LogHandler().getInstance(UserService.class);*   proxy.doSomething();** 输出结果:*   之前*   执行业务*   之后* * @author hrui* @date 2025/4/10 16:03*/
public class LogHandler implements MethodInterceptor {/*** 创建代理对象** @param clazz 目标类的 Class 对象* @return 被代理后的实例对象*/public Object getInstance(Class<?> clazz) {Enhancer enhancer = new Enhancer();             // 创建增强器enhancer.setSuperclass(clazz);                  // 设置父类(被代理的目标类)enhancer.setCallback(this);                     // 设置方法拦截器回调return enhancer.create();                       // 创建代理对象}/*** 拦截方法逻辑(类似 AOP)** @param obj           代理对象* @param method        被调用的方法* @param args          方法参数* @param proxy         方法代理对象(用于调用原始方法)* @return 方法返回值(必须返回原值,否则会丢失结果)*/@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {before();                                        // 调用前增强Object result = proxy.invokeSuper(obj, args);   // 调用原始方法(非反射!)after();                                         // 调用后增强return result;}private void before() {System.out.println("之前");}private void after() {System.out.println("之后");}
}

调用

package com.hrui.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;/*** @author hrui* @date 2025/4/10 15:59*/
public class CglibDemo {public static void main(String[] args) {UserService proxy = (UserService) new LogHandler().getInstance(UserService.class);proxy.doSomething();}
}

注意 JDK17中

因为 CGLIB 使用反射访问了 java.lang.ClassLoader.defineClass(...) 方法,而这个方法从 JDK 16+ 开始默认被封闭需要手动开放访问权限。 

需要添加JVM参数    

--add-opens java.base/java.lang=ALL-UNNAMED

匿名内部类方式

package com.hrui.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;/*** @author hrui* @date 2025/4/10 15:59*/
public class CglibDemo {
//    public static void main(String[] args) {
//        UserService proxy = (UserService) new LogHandler().getInstance(UserService.class);
//        proxy.doSomething();
//    }//用匿名内部类方式public static void main(String[] args) {// 目标类class UserService {public void sayHello() {System.out.println("执行业务逻辑");}}// 创建代理对象(使用匿名内部类作为拦截器)UserService proxy = (UserService) Enhancer.create(UserService.class, // 设置父类new MethodInterceptor() {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxyMethod) throws Throwable {System.out.println("之前");Object result = proxyMethod.invokeSuper(obj, args); // 调用原始方法System.out.println("之后");return result;}});proxy.sayHello(); // 调用代理方法}
}

ByteBuddy

ByteBuddy 不仅仅能用来创建代理,它的能力远远超过“代理”——它是一个通用的 Java 字节码操作和生成框架。

  • 基于 ASM 构建的字节码生成工具

  • 支持动态创建类、增强已有类、方法拦截、注解处理等

  • API 语义化、链式调用、可读性强

  • 可用于运行时 / 构建期(AOT)

添加依赖

<dependency>
    <groupId>net.bytebuddy</groupId>
    <artifactId>byte-buddy</artifactId>
    <version>1.14.11</version>
</dependency>

Javassist

ASM

http://www.dtcms.com/a/586189.html

相关文章:

  • STM32H743-ARM例程41-FMC_INDEP
  • 网站怎么申请百度小程序室内设计师网上培训班
  • 【Java 并发编程】线程创建 6 种方式:Thread/Runnable/Callable 核心类解析+线程池使用说明
  • 第四课:时序逻辑进阶 - 有限状态机(FSM)设计
  • Unicode全字符集加解密工具 - 强大的编码转换GUI应用
  • 网站管理和维护设计师学编程能自己做网站吗
  • PyInstaller 工具使用文档及打包教程
  • 怎么建商业网站外国广告公司网站
  • USB Gadget 技术
  • 常州小型网站建设北京电商网站开发公司哪家好
  • 1108秋招随记
  • 做自己视频教程的网站wordpress去除谷歌
  • 咋把网站制作成软件建设网站需要注意什么手续
  • 线程4.2
  • SOAR:利用状态空间模型和可编程梯度进行航空影像中小目标物体检测的进展
  • 开一个网站需要多少钱网站开发工作量评估
  • [SPSS] SPSS数据的保存
  • Verilog中+:和 -:
  • 清理空壳网站做网站的程序员工资大约月薪
  • 架构设计:基于拼多多 API 构建商品数据实时同步服务
  • 常州建设局下属网站深圳市住房和建设局高泉
  • SQL时间函数全解析从基础日期处理到高级时间序列分析
  • 单片机通信协议--USART(串口通信)
  • 1.21 Profiler提供的API
  • 网站建设维护的知识wordpress搜索被攻击
  • 网站的文件夹wordpress引导页
  • 自然语言处理实战——基于k近邻法的文本分类
  • 柳南网站建设珠海市横琴建设局网站
  • 11.8 脚本网页 塔防游戏
  • FreeRTOS 使用目录