How do I define a specific bean with a qualifier that would designate a specific bean for its dependancies?

Viewed 33

First thanks for taking the time help. You are all Awesome!

My question: Say i have some nested properties in my application.yml

regions:
 region1:
  delayTime: 10
  threads: 2
 region2:
  delayTime: 5
  threads: 1

and a respective component with a config for the regions

@Component
public class Region{
   public int delayTime;
   public int threads;
}
@Configuration
public class RegionConfig{
   @Bean("region1props")
   @ConfigurationProperties(prefix ="regions.region1")
   public Region getRegion1(){
        returns new Region();
    }

   @Bean("region2props")
   @ConfigurationProperties(prefix ="regions.region2")
   public Region getRegion2(){
        returns new Region();
    }

}

If say I also had a RegionHandler Component that had Region as a dependency:

@Component
public class RegionHandler{
 @AutoWired 
 Region region;
}

ULTIMATELY i want a RegionOnePublisher and RegionTwoPublisher Component with no config:

@Component
public class RegionOnePublisher{
  @Autowired
   RegionHandler regionOne;// <-- need to configure Region depenandcy as "region1props" bean 
}
//----------------------------------------------
@Component
public class RegionTwoPublisher{
  @Autowired
   RegionHandler regionTwo; // <-- need to configure Region depenandcy as "region2props" bean
} 

How would I go about defining the config class for RegionHandler object such that @Bean("region1props") is the Region bean dependancy injected for a RegionHandler regionOne and @Bean("region2props") as the Region bean dependancy for RegionHandler regionTwo?

What I have: [Edited]

@Component
public class RegionOnePublisher{
  @Autowired
  @Qualifier("regionOneProps")
   RegionHandler regionOne;// <-- need to configure Region depenandcy as "region1props" bean 
}
//----------------------------------------------
@Component
public class RegionTwoPublisher{
  @Autowired
  @Qualifier("regionTwoProps")
   RegionHandler regionTwo; // <-- need to configure Region depenandcy as "region2props" bean
} 
}

Thanks Guys!

1 Answers

If you use Constructor injection on RegionHandler and not annotate that class with @Component, it should help you to use specific Region for creating the bean.

public class RegionHandler {

    Region region;

    public RegionHandler(Region region) {
        this.region = region;
    }
}

Now your handlers can be registered as beans by changing your config file a bit

@Configuration
public class RegionHandlerConfig{

    @Bean("regionHandler1")
    public RegionHandler getRegionHandlerOne(@Qualifier("region1props") Region region) {
        return new RegionHandler(region);
    }

    @Bean("regionHandler2")
    public RegionHandler getRegionHandlerTwo(@Qualifier("region2props") Region region) {
        return new RegionHandler(region);
    }
}

I haven't compiled and checked but this is the basic idea.

Also, do look into whether this pattern would be extendable. I am guessing you have specific logic in the handler and publisher for each region. But I wonder how you would be able to extend it if you have to add more regions. A better structure might be to take a map of the regions from the config and have only one bean of handler and publisher each.

Related