You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何以编程方式动态注入抽象类的CDI托管Bean实例?

动态生成GenericScheduleController实例的可行方案

你的需求是可行的,但因为GenericScheduleController是抽象类无法直接实例化,需要通过动态生成子类+CDI编程式注入的方式实现。以下是具体实现思路和代码示例:

核心思路

  1. 动态生成GenericScheduleController的子类,实现抽象方法getLabel(),让它返回传入的chaine参数。
  2. 通过CDI的编程式API(Instance)获取该动态子类的实例,确保CDI自动处理@Inject依赖注入和@PostConstruct生命周期方法。

具体实现(基于ByteBuddy字节码生成库)

ByteBuddy是常用的字节码生成工具,能方便地动态创建子类。

1. 引入ByteBuddy依赖(Maven示例)

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

2. 编写工厂方法实现

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.implementation.MethodDelegation;
import net.bytebuddy.matcher.ElementMatchers;
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;

public class ScheduleControllerFactory {

    @Inject
    private Instance<GenericScheduleController> controllerInstance;

    public GenericScheduleController getScheduleController(String chaine) {
        try {
            // 动态生成子类:实现getLabel()返回指定字符串,并添加@Dependent作用域
            Class<? extends GenericScheduleController> dynamicSubclass = new ByteBuddy()
                    .subclass(GenericScheduleController.class)
                    .annotateWith(Dependent.class) // 标记为CDI的依赖作用域,每次获取新实例
                    .method(ElementMatchers.named("getLabel"))
                    .intercept(MethodDelegation.to(new Object() {
                        @SuppressWarnings("unused")
                        public String getLabel() {
                            return chaine;
                        }
                    }))
                    .make()
                    .load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
                    .getLoaded();

            // 通过CDI Instance获取实例,自动处理依赖注入和@PostConstruct
            return controllerInstance.select(dynamicSubclass).get();
        } catch (Exception e) {
            throw new RuntimeException("生成动态ScheduleController失败", e);
        }
    }
}

关键细节说明

  • 动态子类作用域:添加@Dependent注解确保每次调用getScheduleController()都能获取新实例,符合你的需求。
  • CDI生命周期处理:通过Instance.select().get()获取实例时,CDI会自动注入Service实例,并执行@PostConstruct的init()方法,此时getLabel()返回的就是传入的chaine参数。
  • 字节码生成工具选择:如果不想用ByteBuddy,也可以用CGLIB,但ByteBuddy的API更简洁易用。Java原生的Proxy只能代理接口,无法处理抽象类,所以不适用。

内容的提问来源于stack exchange,提问作者olivier P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 16:05:38