私は、アノテーションを使ってクラスパスから取得されたSpring beanをたくさん持っています。
@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {
// Implementation omitted
}
Spring XMLファイルには、 PropertyPlaceholderConfigurer が定義されています。
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/WEB-INF/app.properties" />
</bean>
App.properitesのプロパティの1つを上記のBeanに注入します。私は単純にこんなことはできません
<bean class="com.example.PersonDaoImpl">
<property name="maxResults" value="${results.max}"/>
</bean>
PersonDaoImplはSpring XMLファイルでは機能しないため(アノテーションを介してクラスパスから取得されます)。私は以下のものまで持っています:
@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {
@Resource(name = "propertyConfigurer")
protected void setProperties(PropertyPlaceholderConfigurer ppc) {
// Now how do I access results.max?
}
}
しかし、私がppc
からどのように私が興味を持っている財産にアクセスするかは私には明確ではありませんか?
ELのサポートを使用してSpring 3でこれを行うことができます。例:
@Value("#{systemProperties.databaseName}")
public void setDatabaseName(String dbName) { ... }
@Value("#{strategyBean.databaseKeyGenerator}")
public void setKeyGenerator(KeyGenerator kg) { ... }
systemProperties
は暗黙的なオブジェクトで、strategyBean
はBeanの名前です。
もう1つの例は、Properties
オブジェクトからプロパティを取得するときに機能します。また、@Value
をフィールドに適用できることも示しています。
@Value("#{myProperties['github.oauth.clientId']}")
private String githubOauthClientId;
これは ブログ投稿です 私はもう少し情報のためにこれについて書きました。
個人的に私はSpring 3.0でこの新しい方法を気に入っています ドキュメントから :
private @Value("${propertyName}") String propertyField;
ゲッターやセッターはありません。
Configを介してプロパティをロードします。
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:propertyFile.properties" name="propertiesBean"/>
さらに嬉しいことに、IntelliJのEL式のクリックを制御することさえできます。それによって、プロパティ定義が表示されます。
完全に 非xmlバージョン :もあります。
@PropertySource("classpath:propertyFile.properties")
public class AppConfig {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
Spring 3.0.0M3 に新しいアノテーション@Value
があります。 @Value
は#{...}
式だけでなく${...}
プレースホルダーもサポートします
<context:property-placeholder ... />
は、PropertyPlaceholderConfigurerと同等のXMLです。
例:applicationContext.xml
<context:property-placeholder location="classpath:test.properties"/>
コンポーネントクラス
private @Value("${propertyName}") String propertyField;
もう1つの方法は、以下に示すappProperties Beanを追加することです。
<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>
このBeanを取得すると、Java.util.Properties
から値が読み取られるresults.max
という名前のプロパティを含むapp.properties
にキャストできます。繰り返しますが、このBeanは@Resourceアノテーションを介して任意のクラスに(Java.util.Propertiesのインスタンスとして)依存性注入できます。
個人的には、appPropertiesによって公開されるプロパティを厳密に制限することができ、app.propertiesを2回読み取る必要がないため、この解決策をお勧めします(私が提案したものよりも)。
プロダクション用と開発用のオーバーライドの2つのプロパティファイルが必要です(デプロイされません)。
自動配線可能なProperties BeanとPropertyConfigurerの両方を持つには、次のように書くことができます。
<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>
propertyConfigurerのProperties Beanを参照してください。
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="appProperties" />
</bean>
春の道:private @Value("${propertyName}") String propertyField;
springの "PropertyPlaceholderConfigurer"クラスを使って値を注入する新しい方法です。別の方法は電話することです
Java.util.Properties props = System.getProperties().getProperty("propertyName");
注:@Valueの場合、 static propertyFieldを使用することはできません。これは非静的のみでなければならず、それ以外の場合はnullを返します。これを修正するために、静的フィールドに非静的セッターが作成され、そのセッターの上に@Valueが適用されます。
自分のクラスに注釈を付けることもできます。
@PropertySource("classpath:/com/myProject/config/properties/database.properties")
そしてこのような変数を持ってください:
@Autowired
private Environment env;
これで、あなたはすべてのあなたの財産にアクセスすることができます:
env.getProperty("database.connection.driver")
Spring 3に入る前に - アノテーションを使ってあなたのbeanに直接プロパティ定数を注入することができます - 私は同じことをするPropertyPlaceholderConfigurer beanのサブクラスを書きました。だから、あなたはあなたのプロパティセッターをマークアップすることができ、SpringはあなたのプロパティをあなたのBeanに自動配線します:
@Property(key="property.key", defaultValue="default")
public void setProperty(String property) {
this.property = property;
}
注釈は次のとおりです。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface Property {
String key();
String defaultValue() default "";
}
PropertyAnnotationAndPlaceholderConfigurerは次のとおりです。
public class PropertyAnnotationAndPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
private static Logger log = Logger.getLogger(PropertyAnnotationAndPlaceholderConfigurer.class);
@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties properties) throws BeansException {
super.processProperties(beanFactory, properties);
for (String name : beanFactory.getBeanDefinitionNames()) {
MutablePropertyValues mpv = beanFactory.getBeanDefinition(name).getPropertyValues();
Class clazz = beanFactory.getType(name);
if(log.isDebugEnabled()) log.debug("Configuring properties for bean="+name+"["+clazz+"]");
if(clazz != null) {
for (PropertyDescriptor property : BeanUtils.getPropertyDescriptors(clazz)) {
Method setter = property.getWriteMethod();
Method getter = property.getReadMethod();
Property annotation = null;
if(setter != null && setter.isAnnotationPresent(Property.class)) {
annotation = setter.getAnnotation(Property.class);
} else if(setter != null && getter != null && getter.isAnnotationPresent(Property.class)) {
annotation = getter.getAnnotation(Property.class);
}
if(annotation != null) {
String value = resolvePlaceholder(annotation.key(), properties, SYSTEM_PROPERTIES_MODE_FALLBACK);
if(StringUtils.isEmpty(value)) {
value = annotation.defaultValue();
}
if(StringUtils.isEmpty(value)) {
throw new BeanConfigurationException("No such property=["+annotation.key()+"] found in properties.");
}
if(log.isDebugEnabled()) log.debug("setting property=["+clazz.getName()+"."+property.getName()+"] value=["+annotation.key()+"="+value+"]");
mpv.addPropertyValue(property.getName(), value);
}
}
for(Field field : clazz.getDeclaredFields()) {
if(log.isDebugEnabled()) log.debug("examining field=["+clazz.getName()+"."+field.getName()+"]");
if(field.isAnnotationPresent(Property.class)) {
Property annotation = field.getAnnotation(Property.class);
PropertyDescriptor property = BeanUtils.getPropertyDescriptor(clazz, field.getName());
if(property.getWriteMethod() == null) {
throw new BeanConfigurationException("setter for property=["+clazz.getName()+"."+field.getName()+"] not available.");
}
Object value = resolvePlaceholder(annotation.key(), properties, SYSTEM_PROPERTIES_MODE_FALLBACK);
if(value == null) {
value = annotation.defaultValue();
}
if(value == null) {
throw new BeanConfigurationException("No such property=["+annotation.key()+"] found in properties.");
}
if(log.isDebugEnabled()) log.debug("setting property=["+clazz.getName()+"."+field.getName()+"] value=["+annotation.key()+"="+value+"]");
mpv.addPropertyValue(property.getName(), value);
}
}
}
}
}
}
好みに合わせて自由に変更してください
前述のように@Value
が役目を果たし、あなたがその中に春のELを持つことができるのでそれはかなり柔軟です。
ここにいくつかの例があります。
//Build and array from comma separated parameters
//Like currency.codes.list=10,11,12,13
@Value("#{'${currency.codes.list}'.split(',')}")
private List<String> currencyTypes;
set
からlist
を取得するもう1つの方法
//If you have a list of some objects like (List<BranchVO>)
//and the BranchVO has areaCode,cityCode,...
//You can easily make a set or areaCodes as below
@Value("#{BranchList.![areaCode]}")
private Set<String> areas;
プリミティブ型に値を設定することもできます。
@Value("${amount.limit}")
private int amountLimit;
静的メソッドを呼び出すことができます。
@Value("#{T(foo.bar).isSecurityEnabled()}")
private boolean securityEnabled;
あなたは論理を持つことができます
@Value("#{T(foo.bar).isSecurityEnabled() ? '${security.logo.path}' : '${default.logo.path}'}")
private String logoPath;
考えられる解決策は、同じプロパティファイルから読み取る2番目のBeanを宣言することです。
<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"/>
'appProperties'という名前のBeanはJava.util.Properties型で、上記の@Resource属性を使用して依存性を注入できます。
Spring 2.5を使い続けているのであれば、それぞれのプロパティに対してBeanを定義し、それらを修飾子を使って注入することができます。このような:
<bean id="someFile" class="Java.io.File">
<constructor-arg value="${someFile}"/>
</bean>
そして
@Service
public class Thing
public Thing(@Qualifier("someFile") File someFile) {
...
見やすくはありませんが、作業は完了です。
私にとっては、それは@ラッキーの答えでした。具体的には、
AutowiredFakaSource fakeDataSource = ctx.getBean(AutowiredFakaSource.class);
from キャプテンデバッグページ
それは私の問題を修正しました。私はApplicationContextベースのアプリケーションをコマンドラインから実行しています。Soに関する多くのコメントから判断すると、SpringはこれらをMVCベースのアプリケーションとは異なる方法で接続しています。
Spring Beansへのプロパティ値の自動配線:
アプリケーションコンテキストを読み込むときに@Autowiredを使用して、あるオブジェクトを別のオブジェクトに挿入するようSpringに指示できることはほとんどの人が知っています。あまり知られていないナゲットの情報は、@ Valueアノテーションを使用してプロパティファイルからBeanの属性に値を注入することもできるということです。詳細についてはこの記事を参照してください...
プロパティをBeanにインジェクトするのに最も便利な方法はセッターメソッドだと思います。
例:
package org.some.beans;
public class MyBean {
Long id;
String name;
public void setId(Long id) {
this.id = id;
}
public Long getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Bean XML定義:
<bean id="Bean1" class="org.some.beans.MyBean">
<property name="id" value="1"/>
<property name="name" value="MyBean"/>
</bean>
名前付きproperty
メソッドごとにsetProperty(value)
が呼び出されます。
この方法は、1つの実装に基づいて複数のBeanが必要な場合に特に役立ちます。
たとえば、xmlにもう1つBeanを定義したとします。
<bean id="Bean2" class="org.some.beans.MyBean">
<property name="id" value="2"/>
<property name="name" value="EnotherBean"/>
</bean>
それから、次のようにコーディングします。
MyBean b1 = appContext.getBean("Bean1");
System.out.println("Bean id = " + b1.getId() + " name = " + b1.getName());
MyBean b2 = appContext.getBean("Bean2");
System.out.println("Bean id = " + b2.getId() + " name = " + b2.getName());
印刷します
Bean id = 1 name = MyBean
Bean id = 2 name = AnotherBean
だから、あなたの場合は、このようになります。
@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {
Long maxResults;
public void setMaxResults(Long maxResults) {
this.maxResults = maxResults;
}
// Now use maxResults value in your code, it will be injected on Bean creation
public void someMethod(Long results) {
if (results < maxResults) {
...
}
}
}
より柔軟な設定が必要な場合は、Settings4jPlaceholderConfigurerを試してください。 http://settings4j.sourceforge.net/currentrelease/configSpringPlaceholder.html
私たちのアプリケーションでは、次のものを使用します。
Key-value-Sourceが最初にチェックされるデフォルトの順序は、次のとおりです。
http://settings4j.sourceforge.net/currentrelease/configDefault.html
クラスパスのsettings4j.xml(log4j.xmlに正確)を使ってカスタマイズできます。
あなたの意見を聞かせてください:[email protected]
親切に
ハラルド