惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
CERT Recently Published Vulnerability Notes
G
Google Developers Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
宝玉的分享
宝玉的分享
Microsoft Security Blog
Microsoft Security Blog
Jina AI
Jina AI
L
LangChain Blog
博客园_首页
有赞技术团队
有赞技术团队
The Register - Security
The Register - Security
GbyAI
GbyAI
Blog — PlanetScale
Blog — PlanetScale
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
J
Java Code Geeks
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Security Archives - TechRepublic
Security Archives - TechRepublic
量子位
雷峰网
雷峰网
Security Latest
Security Latest
博客园 - 【当耐特】
V2EX - 技术
V2EX - 技术
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
IT之家
IT之家
爱范儿
爱范儿
S
Schneier on Security
N
News | PayPal Newsroom
H
Help Net Security
Recent Announcements
Recent Announcements
Martin Fowler
Martin Fowler
N
News and Events Feed by Topic
C
Cyber Attacks, Cyber Crime and Cyber Security
U
Unit 42
博客园 - 司徒正美
Forbes - Security
Forbes - Security
P
Proofpoint News Feed
W
WeLiveSecurity
Cisco Talos Blog
Cisco Talos Blog
小众软件
小众软件
The Cloudflare Blog
AWS News Blog
AWS News Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
P
Palo Alto Networks Blog
Google DeepMind News
Google DeepMind News
H
Heimdal Security Blog
V
Vulnerabilities – Threatpost
Microsoft Azure Blog
Microsoft Azure Blog
T
Tailwind CSS Blog
G
GRAHAM CLULEY

博客园 - PointNet

log4j2发送消息至Kafka log4j2自定义Appender(输出到文件/RPC服务中) log4j 不同模块输出到不同的文件 shell之磁盘容量检查,配合crontab可以定时清理磁盘 spring注解之@profile MyBatis传入参数为集合 list 数组 map写法 Spring Boot @Autowired 没法自动注入的问题 mysql5.5 uuid做主键与int做主键的性能实测 dom4j解析xml字符串实例 spring自动注入是单例还是多例?单例如何注入多例? Spring中Bean的五个作用域 【总结】瞬时高并发(秒杀/活动)Redis方案 浅谈分布式事务 基于Redis实现分布式锁 MySQL事务隔离级别详解 Redis学习手册(Sorted-Sets数据类型) Redis的快照持久化-RDB与AOF Redis - 事务 ArrayList、Vector、HashMap、HashTable、HashSet的默认初始容量、加载因子、扩容增量
How to do conditional auto-wiring in Spring?
PointNet · 2017-10-13 · via 博客园 - PointNet

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 ${}).