I want to create multiple similar beans dynamically based on the properties file to replace the duplicate code.
Is that a good idea?
My original duplicate code:
@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);
}
}
I have tried with the code given below:
@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);
}
);
}
}
But the above code is not working.
curriculumScheduleServices is map of curriculumScheduleService with different index(i)
You are probably missing @DependsOn
somewhere in your code. Since you are creating beans programmatically there's no guarantee when those beans are going to be available in application context. To enforce order, you can add @DependsOn
to a configuration that uses it. See Example below
Configuration that depends on other configuration that creates beans programatically
@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 that creates beans programatically
@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));
});
}
}
@PostConstruct
public void init() throws BeansException {
Arrays.stream(signSysIds).forEach(
i -> {
String beanName = "/svc/curriculumScheduleService/" + i;
AbstractBeanDefinition bean = BeanDefinitionBuilder.genericBeanDefinition(PubHessianServiceExporter.class)
.addPropertyValue("service", StudentAppServiceFactory.curriculumScheduleServices.get(Integer.parseInt(i)))
.addPropertyValue("serviceInterface", CurriculumScheduleService.class)
.getBeanDefinition();
beanFactory.registerBeanDefinition(beanName, bean);
}
);
}
it work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.