zoukankan      html  css  js  c++  java
  • How to do conditional auto-wiring in Spring?

    ou can implement simple factory bean to do the conditional wiring. Such factory bean can contain complex conditioning logic:

    public MyBeanFactoryBean implements FactoryBean<MyBean> {
    
        // Using app context instead of bean references so that the unused 
        // dependency can be left uninitialized if it is lazily initialized
        @Autowired
        private ApplicationContext applicationContext;
    
        public MyBean getObject() {
            MyBean myBean = new MyBean();
            if (true /* some condition */) {
                myBean.setDependency(applicationContext.getBean(DependencyX.class));
            } else {
                myBean.setDependency(applicationContext.getBean(DependencyY.class));
            }
            return myBean;
        }
    
        // Implementation of isSingleton => false and getObjectType
    
    }

    Maybe a bit better approach is if you use factory bean to create the dependency bean in case you want to have only one such bean in your application context:

    public MyDependencyFactoryBean implements FactoryBean<MyDependency> {
    
        public MyDependency getObject() {
            if (true /* some condition */) {
                return new MyDependencyX();
            } else {
                return new MyDependencyY();
            }
        }
    
        // Implementation of isSingleton => false and getObjectType
    
    }

    SpEL

    With SpEL there are many possibilities. Most common are system property based conditions:

    <bean class="com.example.MyBean">
        <property name="dependency" value="#{systemProperties['foo'] == 'bar' ? dependencyX : dependencyY}" />
    </bean>

    Property placeholder

    You can have property placeholder resolve your bean reference. The dependency name can be part of the application configuration.

    <bean class="com.example.MyBean">
        <property name="dependency" ref="${dependencyName}" />
    </bean>

    Spring profiles

    Usually the condition you want to evaluate means that a whole set of beans should or should not be registered. Spring profiles can be used for this:

    <!-- Default dependency which is referred by myBean -->
    <bean id="dependency" class="com.example.DependencyX" />
    
    <beans profile="myProfile">
        <!-- Override `dependency` definition if myProfile is active -->
        <bean id="dependency" class="com.example.DependencyY" />
    </beans>

    Other methods can mark the bean definition as lazy-init="true", but the definition will be still registered inside application context (and making your life harder when using unqualified autowiring). You can also use profiles with @Component based beans via @Profile annotation.

    Check ApplicationContextInitialier (or this example) to see how you can activate profiles programatically (i.e. based on your condition).

    Java config

    This is why Java based config is being so popular as you can do:

    @Bean
    public MyBean myBean() {
        MyBean myBean = new MyBean();
        if (true /* some condition */) {
            myBean.setDependency(dependencyX());
        } else {
            myBean.setDependency(dependencyY());
        }
        return myBean;
    }

    Of course you can use more or less all configuration methods in the java based config as well (via @Profile@Value or @Qualifier + @Autowired).

    Post processor

    Spring offers numerous hook points and SPIs, where you can participate in the application context life-cycle. This section requires a bit more knowledge of Spring's inner workings.

    BeanFactoryPostProcessors can read and alter bean definitions (e.g. property placeholder ${}resolution is implemented this way).

    BeanPostProcessors can process bean instances. It is possible to check freshly created bean and play with it (e.g. @Scheduled annotation processing is implemented this way).

    MergedBeanDefinitionPostProcessor is extension of bean post processor and can alter the bean definition just before it is being instantiated (@Autowired annotation processing is implemented this way).


    UPDATE Oct 2015

    • Spring 4 has added a new method how to do conditional bean registration via @Conditionalannotation. That is worth checking as well.

    • Of course there are numerous other ways with Spring Boot alone via its @ConditionalOn*.

    • Also note that both @Import and @ComponentScan (and their XML counterparts) undergo property resolution (i.e. you can use ${}).

  • 相关阅读:
    json的序列化 与 反序列化
    苹果审核被拒 2.3.10
    iOS基础问答面试
    论坛类应用双Tableview翻页效果实现
    iOS性能调优之Analyze静态分析
    win10 U盘安装ubuntu16.04双系统
    spring boot实战读书笔记1
    使用springBoot搭建REATFul风格的web demo
    es6编写generator报错
    vue开发环境搭建win10
  • 原文地址:https://www.cnblogs.com/goody9807/p/7659993.html
Copyright © 2011-2022 走看看