programing

주석을 사용하여 구성된 스프링 빈에 속성 값을 삽입하려면 어떻게 해야 합니까?

bestcode 2022. 8. 28. 09:41
반응형

주석을 사용하여 구성된 스프링 빈에 속성 값을 삽입하려면 어떻게 해야 합니까?

수업 경로에서 주석을 통해 가져온 스프링 콩이 많이 있습니다.

@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {
    // Implementation omitted
}

Spring XML 파일에는 PropertyPlaceholderConfigr가 정의되어 있습니다.

<bean id="propertyConfigurer" 
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="/WEB-INF/app.properties" />
</bean> 

위의 콩에 app.properties의 속성 중 하나를 삽입하고 싶습니다.나는 단순히 그런 일을 할 수 없다.

<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콩 이름이에요.

로서, 이 에서는, 「」, 「」, 「」, 「」, 「」, 「R&D」로부터 할 수 .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"/>

인텔리J의 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 ... />속성 플레이스 홀더 설정(Property Placeholder Configr) XML 설정(XML 설정)

예: application Context.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>

할 수 .java.util.Properties이름 붙여진 속성을 포함합니다.results.max은 " "에서 .app.properties이 콩은 (java.util의 인스턴스로) 의존성을 주입할 수 있습니다.@Resource @Resource입니다.

appProperties에 의해 표시되는 속성을 정확히 제한할 수 있고 app.properties를 두 번 읽을 필요가 없기 때문에 개인적으로 이 솔루션을 선호합니다.

말한 바와 같이@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

//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개의 속성 파일이 필요합니다.하나는 실가동용이고 다른 하나는 개발용입니다(전개요

자동 배선이 가능한 Properties Bean과 Property Configr를 모두 사용하려면 다음과 같이 입력합니다.

<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>

Property Configr에서 Properties Bean을 참조합니다.

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="properties" ref="appProperties" />
</bean>

클래스에 주석을 달 수도 있습니다.

@PropertySource("classpath:/com/myProject/config/properties/database.properties")

다음과 같은 변수가 있습니다.

@Autowired
private Environment env;

이제 다음과 같은 방법으로 모든 속성에 액세스할 수 있습니다.

env.getProperty("database.connection.driver")

주석을 사용하여 속성 상수를 콩에 직접 주입할 수 있는 Spring 3을 시작하기 전에 동일한 작업을 수행하는 Property Placeholder Configr bean의 하위 클래스를 작성했습니다.따라서 속성 설정기를 표시하면 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 "";
}

PropertyAnnotationAndPlaceholderConfigr은 다음과 같습니다.

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);
                    }
                }
            }
        }
    }

}

취향에 맞게 자유롭게 변경 가능

★★★★★★★★★★★★★★★★★★:
private @Value("${propertyName}") String propertyField;

는 Spring의 "PropertyPlaceholderConfigr" 클래스를 사용하여 값을 주입하는 새로운 방법입니다.또 다른 방법은 전화하는 것이다.

java.util.Properties props = System.getProperties().getProperty("propertyName");

주의: @Value의 경우 static propertyField는 사용할 수 없습니다.비정적이어야 합니다.그렇지 않으면 null이 반환됩니다.이를 수정하기 위해 스태틱필드에 대해 비 스태틱세터가 생성되고 해당 세터 위에 @Value가 적용됩니다.

가능한 해결책은 같은 속성 파일에서 읽어낸 두 번째 빈을 선언하는 것입니다.

<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'라는 이름의 빈은 java.util 유형입니다.위의 @Resource Attribute를 사용하여 속성 및 종속성을 주입할 수 있습니다.

Spring 2.5를 사용할 수 없는 경우 각 속성에 대해 빈을 정의하고 수식자를 사용하여 주입할 수 있습니다.다음과 같이 합니다.

  <bean id="someFile" class="java.io.File">
    <constructor-arg value="${someFile}"/>
  </bean>

그리고.

@Service
public class Thing
      public Thing(@Qualifier("someFile") File someFile) {
...

가독성이 뛰어나지는 않지만 작업을 완료한다.

스프링 콩에 속성 값 자동 배선:

대부분의 사람들은 @Autowired를 사용하여 Spring이 어플리케이션콘텍스트를 로드할 때 다른 오브젝트에 삽입하도록 지시할 수 있다는 것을 알고 있습니다.덜 알려진 정보 덩어리는 @Value 주석을 사용하여 속성 파일의 값을 빈의 속성에 주입할 수도 있습니다.자세한 내용은 이 게시물을 참조하십시오.

3.0 신상품 || 자동배선 콩값 || 봄 속성값 자동배선

나로서는 @Lucky의 대답이었고, 구체적으로는 그 대사였다.

AutowiredFakaSource fakeDataSource = ctx.getBean(AutowiredFakaSource.class);

[ Captain Debug ]페이지에서

제 문제를 해결했어요.명령줄에서 Application Context 기반 앱을 실행하고 있는데 SO에 대한 많은 코멘트를 보면 Spring은 MVC 기반 앱과 다른 방식으로 연결합니다.

콩에 성질을 주입하는 가장 편리한 방법은 세터법이라고 생각합니다.

예:

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개의 실장에 근거해 복수의 콩이 필요한 경우에 특히 도움이 됩니다.

예를 들어 xml에서 빈을 하나 더 정의하는 경우:

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

구성에 유연성이 더 필요한 경우 Settings4jPlaceholderConfigr:http://settings4j.sourceforge.net/currentrelease/configSpringPlaceholder.html를 사용해 보십시오.

어플리케이션에서 사용하는 것은 다음과 같습니다.

  • PreProd 및 Prod-System을 설정하기 위한 프리퍼런스
  • "mvn jetty:run"에 대한 기본 설정 및 JNDI 환경 변수(JNDI가 기본 설정을 덮어씁니다)
  • UnitTests 시스템 속성(@BeforeClass 주석)

key-value-Source가 처음 체크되는 기본 순서는 다음과 같습니다.
http://settings4j.sourceforge.net/currentrelease/configDefault.html
클래스 패스의 settings4j.xml(log4j.xml에 정확한 값)을 사용하여 커스터마이즈할 수 있습니다.

당신의 의견을 알려주세요: settings 4j-user@lists.소스 포지로 이동합니다.그물

안부를 전하며
하랄.

봄 5에서 가장 쉬운 방법은@ConfigurationPropertieshttps://mkyong.com/spring-boot/spring-boot-configurationproperties-example/ 의 예를 다음에 나타냅니다.

Spring의 "PropertyPlaceholderConfigr" 클래스 사용

bean의 속성으로 동적으로 읽힌 속성 파일을 보여주는 간단한 예

<bean id="placeholderConfig"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>/WEB-INF/classes/config_properties/dev/database.properties</value>
        </list>
    </property> 
</bean>

<bean id="devDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${dev.app.jdbc.driver}"/>
    <property name="jdbcUrl" value="${dev.app.jdbc.url}"/>
    <property name="user" value="${dev.app.jdbc.username}"/>
    <property name="password" value="${dev.app.jdbc.password}"/>
    <property name="acquireIncrement" value="3"/>
    <property name="minPoolSize" value="5"/>
    <property name="maxPoolSize" value="10"/>
    <property name="maxStatementsPerConnection" value="11000"/>
    <property name="numHelperThreads" value="8"/>
    <property name="idleConnectionTestPeriod" value="300"/>
    <property name="preferredTestQuery" value="SELECT 0"/>
</bean> 

속성 파일

dev.app.jdbc.driver=com.bc.jdbc.드라이버

dev.app.jdbc.url=jdbc:dev://localhost:3306/advertisement

dev.app.jdbc.debc=root

dev.app.jdbc.password=root

언급URL : https://stackoverflow.com/questions/317687/how-can-i-inject-a-property-value-into-a-spring-bean-which-was-configured-using

반응형