Mám niekoľko Spring beans, ktoré sa vyberajú z classpath pomocou anotácií, napr.
@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {
// Implementation omitted
}
V súbore Spring XML je definovaný PropertyPlaceholderConfigurer:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/app.properties" />
</bean>
Chcem injektovať jednu z vlastností z app.properites do fazule uvedenej vyššie. Nemôžem jednoducho urobiť niečo ako
<bean class="com.example.PersonDaoImpl">
<property name="maxResults" value="${results.max}"/>
</bean>
Pretože PersonDaoImpl sa nenachádza v súbore Spring XML (vyberá sa z classpath prostredníctvom anotácií). Dostal som sa až k nasledujúcemu:
@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {
@Resource(name = "propertyConfigurer")
protected void setProperties(PropertyPlaceholderConfigurer ppc) {
// Now how do I access results.max?
}
}
Ale'nie je mi jasné, ako sa dostanem k vlastnosti, ktorá ma'zaujíma z ppc
?
Ďalšou alternatívou je pridať fazuľu appProperties znázornenú nižšie:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/app.properties" />
</bean>
<bean id="appProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true"/>
<property name="properties">
<props>
<prop key="results.max">${results.max}</prop>
</props>
</property>
</bean>
Po načítaní môže byť táto bean obsadená do java.util.Properties
, ktorá bude obsahovať vlastnosť s názvom results.max
, ktorej hodnota sa načíta z app.properties
. Opäť, tento bean môže byť závisle injektovaný (ako inštancia java.util.Properties) do akejkoľvek triedy prostredníctvom anotácie @Resource.
Osobne uprednostňujem toto riešenie (pred druhým, ktoré som navrhol), pretože môžete presne obmedziť, ktoré vlastnosti sú vystavené pomocou appProperties, a nemusíte čítať app.properties dvakrát.
Potrebujem mať dva súbory vlastností, jeden pre produkciu a jeden pre vývoj (ktorý nebude nasadený).
Ak chcete mať obidva súbory, Properties Bean, ktorý môže byť autowired, a PropertyConfigurer, môžete napísať:
<bean id="appProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath:live.properties</value>
<value>classpath:development.properties</value>
</list>
</property>
</bean>
a odkazovať na Properties Bean v PropertyConfigurer
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="appProperties" />
</bean>
Možným riešením je deklarovať druhú fazuľu, ktorá bude čítať z rovnakého súboru vlastností:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/app.properties" />
</bean>
<util:properties id="appProperties" location="classpath:/WEB-INF/app.properties"/>
Bean s názvom 'appProperties' je typu java.util.Properties a môže byť závislostne injektovaný pomocou vyššie uvedeného atribútu @Resource.