Skip to content

Instantly share code, notes, and snippets.

@ehdez73
Last active March 8, 2024 19:54
Show Gist options
  • Save ehdez73/b9ac35bf8d230c769309 to your computer and use it in GitHub Desktop.
Save ehdez73/b9ac35bf8d230c769309 to your computer and use it in GitHub Desktop.
Create Beans programatically with Spring Boot
package com.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.stream.Collectors;
@SpringBootApplication
@RestController
@EnableSampleServices
public class DemoApplication {
@Autowired
private List<SampleService> services;
@Autowired @Qualifier("s1")
private SampleService service1;
@Autowired @Qualifier("s2")
private SampleService service2;
@RequestMapping("/services")
public String main(){
return services.stream()
.map( sampleService -> sampleService.getName())
.collect(Collectors.joining(", "));
}
@RequestMapping("/s1")
public String service1(){
return service1.getName();
}
@RequestMapping("/s2")
public String service2(){
return service2.getName();
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
package com.example;
import org.springframework.context.annotation.Import;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(value = RetentionPolicy.RUNTIME)
@Import(SampleServiceConfiguration.class)
public @interface EnableSampleServices {}
package com.example;
public class SampleService {
private String name;
public SampleService(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
package com.example;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import java.util.Arrays;
import java.util.List;
@Configuration
public class SampleServiceConfiguration implements ImportBeanDefinitionRegistrar {
private List<String> names = Arrays.asList("s1", "s2", "s3");
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
names.stream().forEach(
name -> register(registry, name)
);
}
private void register(BeanDefinitionRegistry registry, String name){
BeanDefinition bd = new RootBeanDefinition(SampleService.class);
bd.getConstructorArgumentValues()
.addGenericArgumentValue(name);
registry.registerBeanDefinition(name, bd);
}
}
@natancox
Copy link

Cool, thanks! I think this is the simplest way I found to create Spring Beans dynamically.

Although for RootBeanDefinition the documentation says to typically use GenericBeanDefinition, like this

    BeanDefinition bd = new GenericBeanDefinition();
    bd.setBeanClassName(SampleService.class.getName());

Note to self: injecting other beans is automatic. You do not need to add ConstructorArgumentValues (like in this example)!!

@prinal10
Copy link

prinal10 commented Jun 22, 2018

Hi, is it possible to create a bean dynamically for a class and add annotations on the the created bean. Like:

@InboundChannelAdapter(channel = TransformerChannel.TRANSFORMER_OUTPUT, autoStartup = "false",
        poller = @Poller(value = "customPoller"))
public MessageSource<InputStream> sftpMessageSource() {
    SftpStreamingMessageSource messageSource = new SftpStreamingMessageSource(sftpRemoteFileTemplate,
            null);
    messageSource.setRemoteDirectory(sftpProperties.getSftpDirPath());
    messageSource.setFilter(new SftpPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(),
            "streaming"));
    messageSource.setFilter(new SftpSimplePatternFileListFilter("*.txt"));
    return messageSource;
}

I want to create multiple MessageSource beans dynamically and annotate those beans with the @InboundChannelAdapter. Can you suggest me on how can i achieve that !?

@rohitkrishna094
Copy link

@prinal10 were you able to figure this out?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment