Jak mogę wprowadzić wartość właściwości do fasoli wiosennej, która została skonfigurowana za pomocą adnotacji?

Mam kilka fasolek wiosennych, które są zbierane ze ścieżki klasowej za pomocą adnotacji, np.

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

W pliku XML Spring znajduje się PropertyPlaceholderConfigurer zdefiniowane:

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

Chcę wprowadzić jedną z właściwości z aplikacji.properites do fasoli pokazanej powyżej. I can ' t simply do something like

<bean class="com.example.PersonDaoImpl">
    <property name="maxResults" value="${results.max}"/>
</bean>

Ponieważ PersonDaoImpl nie występuje w pliku XML Spring (jest pobierany ze ścieżki klas poprzez adnotacje). Mam tak daleko jak "po": {]}

@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 jest dla mnie jasne, jak uzyskać dostęp do interesującej mnie nieruchomości z ppc?

Author: Peter Mularien, 2008-11-25

17 answers

Możesz to zrobić wiosną 3 używając wsparcia EL. Przykład:

@Value("#{systemProperties.databaseName}")
public void setDatabaseName(String dbName) { ... }

@Value("#{strategyBean.databaseKeyGenerator}")
public void setKeyGenerator(KeyGenerator kg) { ... }

systemProperties jest obiektem niejawnym, a {[3] } jest nazwą fasoli.

Jeszcze jeden przykład, który działa, gdy chcesz pobrać właściwość z Properties obiektu. Pokazuje również, że możesz zastosować @Value do pól:

@Value("#{myProperties['github.oauth.clientId']}")
private String githubOauthClientId;

Oto blog post pisałem o tym dla trochę więcej informacji.

 274
Author: Willie Wheeler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-31 17:05:54

Osobiście uwielbiam ten nowy sposób na wiosnę 3.0 z docs :

private @Value("${propertyName}") String propertyField;
Żadnych getterów i seterów!

Z właściwościami ładowanymi przez config:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
      p:location="classpath:propertyFile.properties" name="propertiesBean"/>

Aby rozwinąć moją radość, mogę nawet kontrolować wyrażenie EL w IntelliJ i sprowadza mnie to do definicji własności!

Istnieje również całkowicie wersja non xml:

@PropertySource("classpath:propertyFile.properties")
public class AppConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }
 135
Author: barrymac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-30 08:07:38

Jest nowa adnotacja @Value W Spring 3.0. 0M3. @Value obsługuje nie tylko #{...} wyrażenia, ale także ${...} placeholdery

 119
Author: AdrieanKhisbe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-17 21:49:29

<context:property-placeholder ... /> jest odpowiednikiem XML dla PropertyPlaceholderConfigurer.

Przykład: applicationkontekst.xml

<context:property-placeholder location="classpath:test.properties"/>  

Klasa komponentu

 private @Value("${propertyName}") String propertyField;
 30
Author: shane lee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-31 15:19:05

Inną alternatywą jest dodanie appProperties Bean pokazanych poniżej:

<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 pobraniu fasola może być rzucona na java.util.Properties, która będzie zawierać właściwość o nazwie results.max, której wartość jest odczytywana z app.properties. Ponownie, fasola ta może być iniekcją zależności (jako instancja Javy.util.Właściwości) do dowolnej klasy poprzez adnotację @ Resource.

Osobiście wolę to rozwiązanie (od drugiego, które zaproponowałem), ponieważ można dokładnie ograniczyć, które właściwości są narażone przez appProperties, a nie musisz przeczytać aplikację.właściwości dwa razy.

 14
Author: Dónal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-03 12:07:06

Muszę mieć dwa pliki właściwości, jeden dla produkcji i nadpisanie dla rozwoju (które nie zostaną wdrożone).

Aby mieć obie właściwości, które mogą być autowirowane oraz PropertyConfigurer, możesz napisać:

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

I odwoływać się do Właściwości Bean w PropertyConfigurer

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="properties" ref="appProperties" />
</bean>
 9
Author: Willi aus Rohr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-26 07:19:32

Zanim otrzymamy Spring 3-który pozwala na wprowadzanie stałych właściwości bezpośrednio do Twoich beans za pomocą adnotacji-napisałem podklasę PropertyPlaceholderConfigurer bean, która robi to samo. Możesz więc oznaczyć swoje ustawienia nieruchomości, a Wiosna automatycznie połączy je z fasolą w ten sposób:]}

@Property(key="property.key", defaultValue="default")
public void setProperty(String property) {
    this.property = property;
}

Adnotacja jest następująca:

@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.METHOD, ElementType.FIELD})
public @interface Property {
    String key();
    String defaultValue() default "";
}

PropertyAnnotationAndPlaceholderconfigurer jest następujący:

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

}

Zapraszam do modyfikacji do smak

 6
Author: Ricardo Gladwell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-23 11:18:21

Możesz też przypisać klasę:

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

I mieć taką zmienną:

@Autowired
private Environment env;

Teraz możesz uzyskać dostęp do wszystkich swoich właściwości w ten sposób:

env.getProperty("database.connection.driver")
 6
Author: Alexis Gamarra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-09 20:01:27

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

Jest nowym sposobem wprowadzania wartości za pomocą klasy "PropertyPlaceholderConfigurer" Springa. Innym sposobem jest wywołanie

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

Uwaga: Dla @Value, nie można używać static propertyField, powinno być tylko niestatyczne, w przeciwnym razie zwraca null. Aby to naprawić, dla pola statycznego tworzony jest niestatyczny setter, a nad tym seterem stosowana jest wartość@.

 6
Author: hi.nitish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-25 19:56:09

Możliwym rozwiązaniem jest zadeklarowanie drugiej fasoli, która odczytuje z tego samego pliku właściwości:

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

Fasola o nazwie 'appProperties' jest typu java.util.Właściwości i mogą być zależne wstrzykiwane przy użyciu @Resource attruibute pokazanego powyżej.

 5
Author: Dónal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-25 17:22:27

Jeśli utknąłeś w Spring 2.5, możesz zdefiniować fasolę dla każdej z Twoich właściwości i wprowadzić je za pomocą kwalifikatorów. TAK:

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

I

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

Nie jest zbyt czytelny, ale wykonuje zadanie.

 3
Author: Nik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-17 14:28:28

Jak wspomniano @Value robi to zadanie i jest dość elastyczny, ponieważ można w nim mieć spring EL.

Oto kilka przykładów, które mogą być pomocne:

//Build and array from comma separated parameters 
//Like currency.codes.list=10,11,12,13
@Value("#{'${currency.codes.list}'.split(',')}") 
private List<String> currencyTypes;

Inny, aby uzyskać set z 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;

Można również ustawić wartości dla typów prymitywnych.

@Value("${amount.limit}")
private int amountLimit;

Możesz wywołać metody statyczne:

@Value("#{T(foo.bar).isSecurityEnabled()}")
private boolean securityEnabled;

Możesz mieć logikę

@Value("#{T(foo.bar).isSecurityEnabled() ? '${security.logo.path}' : '${default.logo.path}'}")
private String logoPath;
 3
Author: Alireza Fattahi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-27 11:55:14

Autowirowanie wartości nieruchomości do fasoli wiosennej:

Większość ludzi wie, że możesz użyć @Autowired, aby powiedzieć Spring, aby wstrzyknął jeden obiekt do drugiego, gdy ładuje kontekst aplikacji. Mniej znaną cechą informacji jest to, że można również użyć adnotacji @Value, aby wprowadzić wartości z pliku właściwości do atrybutów fasoli. zobacz ten post, aby uzyskać więcej informacji...

Nowe rzeczy na wiosnę 3.0 / / autowirowanie wartości fasoli / / autowirowanie nieruchomości wartości na wiosnę

 2
Author: Lucky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-02 12:39:35

Dla mnie to była odpowiedź @ Lucky, a konkretnie linia

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

From The Captain debug page

To naprawiło mój problem. Mam aplikację opartą na aplikacji działającą z wiersza poleceń, a sądząc po liczbie komentarzy na tak, Spring łączy je inaczej niż aplikacje oparte na MVC.
 2
Author: ben3000,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-18 05:24:25

Jeśli potrzebujesz większej elastyczności konfiguracji, spróbuj Settings4jPlaceholderConfigurer: http://settings4j.sourceforge.net/currentrelease/configSpringPlaceholder.html

W naszej aplikacji używamy:

  • Preferencje konfiguracji systemu PreProd i Prod
  • preferencje i zmienne środowiskowe JNDI (JNDI nadpisuje preferencje) dla "mvn jetty: run"
  • Właściwości systemu dla UnitTests (@BeforeClass adnotacja)

The domyślna kolejność, która klucz-wartość-źródło jest sprawdzana jako pierwsza, jest opisana w:
http://settings4j.sourceforge.net/currentrelease/configDefault.html
Można go dostosować za pomocą settings4j.xml (dokładne do log4j.xml) w swojej klasie.

Daj znać swoją opinię: [email protected]

Z przyjaznymi pozdrowieniami,
Harald

 0
Author: brabenetz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-13 18:05:50

Myślę, że najwygodniejszym sposobem wstrzykiwania właściwości do fasoli jest metoda settera.

Przykład:

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

Definicja xml Bean:

<bean id="Bean1" class="org.some.beans.MyBean">
    <property name="id" value="1"/>
    <property name="name" value="MyBean"/>
</bean>

Dla każdej podanej metody property zostanie wywołana metoda setProperty(value).

Ten sposób jest szczególnie pomocny, jeśli potrzebujesz więcej niż jednej fasoli opartej na jednej implementacji.

Na przykład, jeśli zdefiniujemy jeszcze jedną fasolę w xml:

<bean id="Bean2" class="org.some.beans.MyBean">
    <property name="id" value="2"/>
    <property name="name" value="EnotherBean"/>
</bean>

Następnie kod w ten sposób:

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

Wydrukuje

Bean id = 1 name = MyBean
Bean id = 2 name = AnotherBean

Więc w Twoim przypadku powinno wyglądać tak:

@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) {
            ...
        }
    }
}
 0
Author: Sergei Pikalev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-20 18:31:47

Użyj klasy "PropertyPlaceholderConfigurer" Springa

Prosty przykład pokazujący Plik Właściwości odczytywany dynamicznie jako właściwość Beana

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

Plik Właściwości

Dev.app.jdbc.kierowca = com.mysql.jdbc.Kierowca

Dev.app.jdbc.url = JDBC: mysql: / / localhost: 3306 / addvertisement

Dev.app.jdbc.username=root

Dev.app.jdbc.password=root

 -1
Author: ravi ranjan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-19 16:52:27