byte-buddy 1.9.6 简述及原理2-更多实例

本文介绍ByteBuddy库1.9.6版本的使用方法及原理,演示了如何利用ByteBuddy创建字节码,实现接口并修改方法行为。通过具体示例,展示了动态类型创建、方法拦截及安全框架原型的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

byte-buddy 1.9.6 简述及原理2-更多实例

概述

示例(https://github.com/undergrowthlinear/byte-buddy-test)

CreateByteCodeSomeTest

 DynamicType.Unloaded unloadedDynamicType;
 
     @Before
     public void before() {
         unloadedDynamicType = new ByteBuddy(ClassFileVersion.JAVA_V8)
             .subclass(Object.class)
             .name("test.Test")
             .implement(First.class)
             .implement(Second.class)
             .method(named("qux")).intercept(DefaultMethodCall.prioritize(First.class))
             .make();
     }
 
     @Test
     public void implemetentTest() throws IOException {
         unloadedDynamicType.saveIn(new File("./target"));
     }
 
     @Test
     public void implemetent2Test() throws IOException, IllegalAccessException, InstantiationException {
         Class<First> cls = unloadedDynamicType.load(getClass().getClassLoader()).getLoaded();
         String str = cls.newInstance().qux();
         System.out.println(str);
         Assert.assertEquals("bar方法改写错误", str, "FOO");
     }
 
     @Test
     public void createMultiTest() throws IllegalAccessException, InstantiationException {
         Foo dynamicFoo = new ByteBuddy()
             .subclass(Foo.class)
             .method(isDeclaredBy(Foo.class)).intercept(FixedValue.value("One!"))
             .method(named("foo")).intercept(FixedValue.value("Two!"))
             .method(named("foo").and(takesArguments(1))).intercept(FixedValue.value("Three!"))
             .make()
             .load(getClass().getClassLoader())
             .getLoaded()
             .newInstance();
         System.out.println(dynamicFoo.bar());
         System.out.println(dynamicFoo.foo());
         System.out.println(dynamicFoo.foo("a"));
         Assert.assertEquals("bar方法改写错误", dynamicFoo.bar(), "One!");
         Assert.assertEquals("foo方法改写错误", dynamicFoo.foo(), "Two!");
         Assert.assertEquals("foo方法改写错误", dynamicFoo.foo("a"), "Three!");
     }
  • implemetentTest与implemetent2Test用于展示创建新的字节码继承Object,实现First/Second接口,同时制定父类方法调用优先级,查看生成的字节码信息
  • createMultiTest用于展示对不同的方法进行转换

Agent 安全框架原型示例

 public static void premain(String arg, Instrumentation inst) {
        new AgentBuilder.Default()
            .type(ElementMatchers.any())
            .transform((builder, type, classLoader, module) -> builder
                .method(ElementMatchers.isAnnotatedWith(Secured.class))
                .intercept(MethodDelegation.to(new SecurityInterceptor())
                    .andThen(SuperMethodCall.INSTANCE)))
            .installOn(inst);
    }
static String user = "ADMIN";

    @RuntimeType
    public void intercept(@AllArguments Object[] allArguments, @Origin Method method) {
        if (!method.getAnnotation(Secured.class).user().equals(user)) {
            throw new IllegalStateException("Wrong user");
        }
        System.out.println("pass security check method:" + method.getName());
    }
  • agent中通过对Secured注解的拦截,将其委托给SecurityInterceptor拦截器对象,对注解上的参数进行判断,进而通过抛出异常控制流程的扭转,更进一步与业务结合的话,需要加上类似ThreadLocal ContextSecurity 机制进行融合
  • 2.添加maven-shade-plugin插件,添加premain
  • 3.com.undergrowth.secure.SecurityAgentMain#main 启动 可通过是否添加 -javaagent参数 查看代理机制有无生效
pass security check method:doSensitiveAction
dangerous doSensitiveAction
Exception in thread "main" java.lang.IllegalStateException: Wrong user
	at com.undergrowth.secure.SecurityInterceptor.intercept(SecurityInterceptor.java:20)
	at com.undergrowth.secure.Service1.deleteDataBase(Service1.java)
	at com.undergrowth.secure.SecurityAgentMain.main(SecurityAgentMain.java:17)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值