【问题标题】:How to get a bean dynamically using Custom Qualifier Annotation如何使用自定义限定符注解动态获取 bean
【发布时间】:2015-11-02 14:12:19
【问题描述】:

我们使用自定义限定符注释来创建和注入 bean。我们如何通过仅指定自定义限定符在运行时动态选择 bean。

自定义限定符:

@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.TYPE,
        ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface PlatformQualifiers {

    public static enum OperatingSystems {
        IOS, ANDROID
    }

    OperatingSystems operatingSystem() default OperatingSystems.IOS;

    public enum DeviceTypes {
        Mobile, Tablet, ANY, Other
    }

    DeviceTypes[] deviceType() default { DeviceTypes.ANY };
}

Bean 接口:

@FunctionalInterface
public interface Platform {

    String getDeviceDetails();
}

Bean 配置:

@Configuration
public class PlatformConfig {

    @Bean
    @PlatformQualifiers(operatingSystem = OperatingSystems.IOS, deviceType = DeviceTypes.Mobile)
    public Platform getIphone6() {
        return () -> "iphone6";
    }

    @Bean
    @PlatformQualifiers(operatingSystem = OperatingSystems.IOS, deviceType = DeviceTypes.Tablet)
    public Platform getIpad() {
        return () -> "ipad3";

    }

    @Bean
    @PlatformQualifiers(operatingSystem = OperatingSystems.ANDROID, deviceType = DeviceTypes.Mobile)
    public Platform getAndroidPhone() {
        return () -> "AndroidPhoneSamsung";
    }

}

当前申请代码:

@Configuration
@ComponentScan
public class MainApplication {

    @Autowired
    @PlatformQualifiers(operatingSystem = OperatingSystems.IOS, deviceType = DeviceTypes.Mobile)
    Platform iphone;


    @Autowired
    @PlatformQualifiers(operatingSystem = OperatingSystems.ANDROID, deviceType = DeviceTypes.Mobile)
    Platform androidPhone;

    public  void getDevice(String osType, String deviceType ) {
        if(osType == "ios" && deviceType == "mobile") {
            System.out.println(iphone.getDeviceDetails());
        }

        if(osType == "android" && deviceType == "mobile") {
            System.out.println(androidPhone.getDeviceDetails());
        }

    }

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MainApplication.class);
        MainApplication mainApplication = context.getBean(MainApplication.class);
        mainApplication.getDevice("ios" ,"mobile");
        mainApplication.getDevice("android" , "mobile");


    }

}

我正在寻找一种解决方案,比如在运行时我可以使用限定符访问 bean,如下所示:

@Configuration
@ComponentScan
public class MainApplication2 {
    @Autowired
    ApplicationContext context;

    public  void getDevice(DeviceTypes deviceType, OperatingSystems osType ) {
           >>>>>>>>>>> Looking of something of type following : 
            Platform p =    context.getBean(some input consisting to identify bean by  deviceType and osType)


            System.out.println(p.getDeviceDetails());
        }

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(MainApplication2.class);
        MainApplication2 application = context.getBean(MainApplication2.class);
        application.getDevice(DeviceTypes.Mobile, OperatingSystems.ANDROID);
    }
}

在这种情况下,如何根据 DeviceTypes 和 OperatingSystems 在运行时从 applicationContext 获取 bean?

【问题讨论】:

  • 四年后仍然没有接近 CDI 优雅的解决方案......难以置信

标签: java spring spring-annotations


【解决方案1】:

其中一种方法是创建Platform bean 的Map 并将其注入到调用getDevice 的bean 中。地图的键可以是设备类型。

另一种方法是让您的 bean 实现 InitializingBeanApplicationContextAware 并在 'afterPropertiesSetin conjuction withfindAnnotationOnBean` 中使用 'getBeansWithAnnotation' 来填充 Map 或动态查找 bean。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多