How to do conditional auto-wiring in Spring? -
has tried auto-wire different beans spring-managed bean based on condition? e.g. if condition met, inject class a, else b? saw in 1 of google search results possible spel (spring expression language), not locate working example.
there multiple ways achieve this. depends on conditioning want perform.
factory bean
you can implement simple factory bean conditional wiring. such factory bean can contain complex conditioning logic:
public mybeanfactorybean implements factorybean<mybean> { // using app context instead of bean references unused // dependency can left uninitialized if lazily initialized @autowired private applicationcontext applicationcontext; public mybean getobject() { mybean mybean = new mybean(); if (true /* condition */) { mybean.setdependency(applicationcontext.getbean(dependencyx.class)); } else { mybean.setdependency(applicationcontext.getbean(dependencyy.class)); } return mybean; } // implementation of issingleton => false , getobjecttype }
maybe bit better approach if use factory bean create dependency bean in case want have 1 such bean in application context:
public mydependencyfactorybean implements factorybean<mydependency> { public mydependency getobject() { if (true /* condition */) { return new mydependencyx(); } else { return new mydependencyy(); } } // implementation of issingleton => false , getobjecttype }
spel
with spel there many possibilities. common 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 bean reference. dependency name can part of application configuration.
<bean class="com.example.mybean"> <property name="dependency" ref="${dependencyname}" /> </bean>
spring profiles
usually condition want evaluate means whole set of beans should or should not registered. spring profiles can used this:
<!-- default dependency referred mybean --> <bean id="dependency" class="com.example.dependencyx" /> <beans profile="myprofile"> <!-- override `dependency` definition if myprofile active --> <bean id="dependency" class="com.example.dependencyy" /> </beans>
other methods can mark bean definition lazy-init="true"
, definition still registered inside application context (and making life harder when using unqualified autowiring). can use profiles @component
based beans via @profile
annotation.
check applicationcontextinitialier
(or example) see how can activate profiles programatically (i.e. based on your condition).
java config
this why java based config being popular can do:
@bean public mybean mybean() { mybean mybean = new mybean(); if (true /* condition */) { mybean.setdependency(dependencyx()); } else { mybean.setdependency(dependencyy()); } return mybean; }
of course can use more or less configuration methods in java based config (via @profile
, @value
or @qualifier
+ @autowired
).
post processor
spring offers numerous hook points , spis, can participate in application context life-cycle. section requires bit more knowledge of spring's inner workings.
beanfactorypostprocessor
s can read , alter bean definitions (e.g. property placeholder ${}
resolution implemented way).
beanpostprocessor
s can process bean instances. possible check freshly created bean , play (e.g. @scheduled
annotation processing implemented way).
mergedbeandefinitionpostprocessor
extension of bean post processor , can alter bean definition before being instantiated (@autowired
annotation processing implemented way).
update oct 2015
spring 4 has added new method how conditional bean registration via
@conditional
annotation. worth checking well.of course there numerous other ways spring boot alone via
@conditionalon*
.also note both
@import
,@componentscan
(and xml counterparts) undergo property resolution (i.e. can use${}
).
Comments
Post a Comment