简体   繁体   中英

Spring-Boot @Bean producer with dynamic parameters

I'm dealing with a set of similar Beans just differing for some properties, and what I'm trying to achieve is to have just a single method producing such a Bean but with the possibility to be "configured" or customized through some parameters, maybe with a custom @Qualifier annotation. Is such a thing possible?

For example, I would like to use this @Annotation as the qualifier for autowiring the different @Beans:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface CustomQualifier {    
    int length();
    int height();
}

Then have just a single method for producing the different @Beans, by reading the parameters of the annotation.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DynamicReportsConfiguration {

    @Bean
    @CustomQualifier // Here I do not want to set the fields' value
    public MyBean produceBean() {
        // TODO Read the fields of the @CustomQualifier
        int length;
        int height;

        return new MyBean(length, height);
    }
}

Then I just want to specify the fields on the injection point, eg:

@Autowired
@CustomQualifier(length=10, height=50)
private MyBean myBean;

How can I achieve such a thing, without having to create a method for each particular combination of the height and length values?

Spring does not support such a thing. Actually spring uses reflection to inject dependencies. spring engine does not know your custom annotation.

I know this is not the direct answer to your question. But just as a workaround, this should work.

@Configuration
public class DynamicReportsConfiguration {

    @Bean
    public BiFunction<Integer, Integer, MyBean> myBeanFactory() {
        return (l, h) -> produceBean(l, h); // or this::produceBean
    }

    @Bean
    public MyBean produceBean(int length, int height) {

        return new MyBean(length, height);
    }
}

And we can use like below

@Autowired
private BiFunction<Integer, Integer, MyBean> myBeanFactory;


MyBean myBean = myBeanFactory.apply(length, height);

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM