Spring: Как динамически создавать похожие бины в Spring Boot? - PullRequest
0 голосов
/ 19 сентября 2019

Я хочу создать несколько похожих бинов динамически на основе файла свойств для замены дублирующего кода.

Это хорошая идея?

Мой оригинальный дубликат кода:

@Configuration
@Order(Integer.MIN_VALUE)
public class HessianFactory {


    public static PubHessianServiceExporter createHessianService(Object service, Class clazz) {
        PubHessianServiceExporter exporter = new PubHessianServiceExporter();
        exporter.setService(service);
        exporter.setServiceInterface(clazz);
        return exporter;
    }

    @Bean("/svc/curriculumScheduleService/1")
    public PubHessianServiceExporter curriculumScheduleService1() {
        return HessianFactory.createHessianService(StudentAppServiceFactory.curriculumScheduleServices.get(1), CurriculumScheduleService.class);
    }

    @Bean("/svc/curriculumScheduleService/2")
    public PubHessianServiceExporter curriculumScheduleService2() {
        return HessianFactory.createHessianService(StudentAppServiceFactory.curriculumScheduleServices.get(2), CurriculumScheduleService.class);
    }

    @Bean("/svc/curriculumScheduleService/3")
    public PubHessianServiceExporter curriculumScheduleService3() {
        return HessianFactory.createHessianService(StudentAppServiceFactory.curriculumScheduleServices.get(3), CurriculumScheduleService.class);
    }

    @Bean("/svc/curriculumScheduleService/5")
    public PubHessianServiceExporter curriculumScheduleService5() {
        return HessianFactory.createHessianService(StudentAppServiceFactory.curriculumScheduleServices.get(5), CurriculumScheduleService.class);
    }
}

Я пробовал с приведенным ниже кодом:

@Configuration
@Order(Integer.MIN_VALUE)
public class HessianFactory {

    @Value("${sign-sys-ids}")
    private String[] signSysIds;
    @Autowired
    private ConfigurableBeanFactory beanFactory;


    public static HessianServiceExporter createHessianService(Object service, Class clazz) {
        HessianServiceExporter exporter = new HessianServiceExporter();
        exporter.setService(service);
        exporter.setServiceInterface(clazz);
        return exporter;
    }

    @PostConstruct
    public void init() throws BeansException {
        Arrays.stream(signSysIds).forEach(
            i -> {
                HessianServiceExporter hessianServiceExporter = createHessianService(
                    StudentAppServiceFactory.curriculumScheduleServices.get(Integer.parseInt(i)), CurriculumScheduleService.class);
                beanFactory.registerSingleton("/svc/curriculumScheduleService/" + i, hessianServiceExporter);
            }
        );
    }
}

Но приведенный выше код не работает.

curriculumScheduleServices является картой учебного планаScheduleService с различными index(i)

1 Ответ

0 голосов
/ 20 сентября 2019

Возможно, вам не хватает @DependsOn где-то в вашем коде.Поскольку вы создаете bean-компоненты программно, нет никакой гарантии, что эти bean-компоненты будут доступны в контексте приложения.Для обеспечения порядка вы можете добавить @DependsOn к конфигурации, которая его использует.См. Пример ниже

Конфигурация, которая зависит от другой конфигурации, которая создает бины программно

@Configuration
@DependsOn("TestConfiguration2")
public class TestConfiguration1 {

  @Autowired
  @Qualifier("/svc/curriculumScheduleService/1")
  private DummyClass dummyClass1;
  @Autowired
  @Qualifier("/svc/curriculumScheduleService/2")
  private DummyClass dummyClass2;
  @Autowired
  @Qualifier("/svc/curriculumScheduleService/3")
  private DummyClass dummyClass3;
  @Autowired
  @Qualifier("/svc/curriculumScheduleService/5")
  private DummyClass dummyClass5;

  @PostConstruct
  public void printBeans() {
    System.out.println(dummyClass1.getVal());
    System.out.println(dummyClass2.getVal());
    System.out.println(dummyClass3.getVal());
    System.out.println(dummyClass5.getVal());
  }
}

Конфигурация, которая создает бины программно

@Configuration("TestConfiguration2")
public class TestConfiguration2 {

  @Autowired
  private ConfigurableBeanFactory beanFactory;

  @PostConstruct
  public void setup() {
    String[] array = {"1", "2", "3", "5"};
    Arrays.stream(array).map(Integer::parseInt).forEach(i -> {
      System.out.println("creating new bean");
      beanFactory.registerSingleton("/svc/curriculumScheduleService/" + i, new DummyClass(i));
    });
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...