Java byte-buddy动态生成子类,Java 动态增加属性和方法

278 篇文章 1 订阅
57 篇文章 0 订阅

================================

©Copyright 蕃薯耀 2022-08-31

蕃薯耀的博客_CSDN博客-蕃薯耀分享,java,js领域博主

Java 使用byte-buddy实现动态生成子类,动态增加属性和方法

一、byte-buddy官网地址

https://bytebuddy.net/
https://github.com/raphw/byte-buddy

二、引入byte-buddy的Maven依赖

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

三、byte-buddy一个简单的例子

Class<?> dynamicType = new ByteBuddy()
  .subclass(Object.class)
  .method(ElementMatchers.named("toString"))
  .intercept(FixedValue.value("Hello World!"))
  .make()
  .load(getClass().getClassLoader())
  .getLoaded();
assertThat(dynamicType.newInstance().toString(), is("Hello World!"));

subclass:声明继承的父类

method:匹配方法

intercept:拦截method匹配后的返回值

四、byte-buddy动态生成子类、属性、方法

	public Object handleEntity(Object data) {
		if(data == null) {
			return data;
		}
		
		ObjectMapper mapper = new ObjectMapper();
        
		String json = "{}";
		try {
			//解决@JsonFormat注解解析不了的问题
			json = mapper.writeValueAsString(data);
			
		} catch (JsonProcessingException e) {
			log.error("Json解析失败:" + e);
			log.error("Json解析失败,data=" + data);
		}
		
		Builder<? extends Object> builder = new ByteBuddy()
				//.redefine(data.getClass())
			  .subclass(data.getClass())
			  //.modifiers(Opcodes.ACC_PUBLIC)
			  //.name("com.builder.vo." + ClassUtil.getClassName(data, true) + "Sub")
			  .name(ClassUtil.getClassName(data, false) + "DynamicTypeBuilder")
		;
		
		
		JSONObject jsonObject = JSONObject.parseObject(json);
		
		for (Field field : ReflectUtil.getFields(data.getClass())) {
			
			Object o = jsonObject.getObject(field.getName(), field.getType());
			
			if(o != null) {
				builder = builder
						//.defineProperty(field.getName(), field.getType())//声明;getter和setter方法
						.method(ElementMatchers.named("get" + StringUtils.capitalize(field.getName())))
						.intercept(FixedValue.value(o))
				;
			}
			
			if (field.getAnnotation(Dict.class) != null) {
				String dictCode = field.getAnnotation(Dict.class).dictCode();
				String dictName = field.getAnnotation(Dict.class).dictName();
				if(StringUtils.isBlank(dictName)) {
					dictName = field.getName() + DICT_SUFFIX;
				}
				
				String dictValue = String.valueOf(jsonObject.get(field.getName()));
				
				//翻译字典值对应的text值
				Optional<String> textValue = Optional.ofNullable(dictCacheService.getText(dictCode, dictValue));
				//jsonObject.put(dictName, textValue.orElse("未知"));
				
				builder = builder.defineField(dictName, String.class, Modifier.PRIVATE)//.value(value)
					.defineMethod("get" + StringUtils.capitalize(dictName), String.class, Modifier.PUBLIC)
					.intercept(FixedValue.value(textValue.orElse("--")))
				;
				
			}
			
		}
		
		Object returnObject = null;
		try {
			
			/*
			//保存生成的类class文件到某个文件夹
			try {
				builder.make().saveIn(new File("c:/0"));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			*/
			
			returnObject =  builder.make()
				.load(getClass().getClassLoader())
				//.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
				.getLoaded()
				.newInstance()
			;
			
		} catch (InstantiationException e) {
			log.error("字典转换出错", e);
			
		} catch (IllegalAccessException e) {
			log.error("字典转换出错", e);
		}
		
		//CglibUtil.copy(data, returnObject);
		
		return returnObject;
		
		//return jsonObject;
		//return data;
	}

defineField:定义字段,即增加字段

defineMethod:定义方法,即增加方法

intercept:拦截defineMethod,设置返回值或者调用的方法

 ================================

©Copyright 蕃薯耀 2022-08-31

蕃薯耀的博客_CSDN博客-蕃薯耀分享,java,js领域博主

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值