주석을 통해 클래스 패스에서 가져온 스프링 콩이 있습니다.
@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의 속성 중 하나를 위에 표시된 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 이름입니다.
Properties
객체 에서 속성을 가져 오려고 할 때 작동하는 또 하나의 예 입니다. 또한 @Value
필드에 적용 할 수 있음을 보여줍니다 .
@Value("#{myProperties['github.oauth.clientId']}")
private String githubOauthClientId;
여기입니다 블로그 게시물 내가 좀 더 정보를 원하시면 이것에 대해 썼다는.
답변
개인적으로 나는 문서 에서 봄 3.0의 새로운 방법을 좋아합니다 .
private @Value("${propertyName}") String propertyField;
게터 나 세터가 없습니다!
구성을 통해 속성을로드하는 경우 :
<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();
}
답변
새로운 주석이 @Value
의 봄 3.0.0M3은 . 표현뿐만 아니라 자리 표시 자도 @Value
지원#{...}
${...}
답변
<context:property-placeholder ... />
PropertyPlaceholderConfigurer와 동등한 XML입니다.
예 : applicationContext.xml
<context:property-placeholder location="classpath:test.properties"/>
컴포넌트 클래스
private @Value("${propertyName}") String propertyField;
답변
다른 대안은 아래에 표시된 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를 두 번 읽을 필요가 없으므로이 솔루션을 제안합니다 (다른 제안보다).
답변
프로덕션 용 파일과 개발 용 재정의 파일 (배포되지 않음)의 두 가지 속성 파일이 필요합니다.
자동 배선 할 수있는 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에서 특성 Bean을 참조하십시오.
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="appProperties" />
</bean>
답변
주석 3을 사용하여 빈에 속성 상수를 직접 주입 할 수있는 Spring 3을 얻기 전에 동일한 작업을 수행하는 PropertyPlaceholderConfigurer 빈의 하위 클래스를 작성했습니다. 따라서 속성 설정자를 마크 업할 수 있고 Spring은 다음과 같이 빈에 속성을 자동 와이어 링합니다.
@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);
}
}
}
}
}
}
취향에 따라 자유롭게 수정하십시오
