Как я могу ввести значение свойства в Spring Bean, который был настроен с помощью аннотаций? - PullRequest
280 голосов
/ 25 ноября 2008

У меня есть куча бобов Spring, которые извлекаются из classpath с помощью аннотаций, например,

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

В XML-файле Spring определено 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 не представлен в XML-файле Spring (он выбирается из пути к классам с помощью аннотаций). Я получил следующее:

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

Ответы [ 17 ]

5 голосов
/ 21 мая 2016

Как уже упоминалось, @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;
3 голосов
/ 17 декабря 2009

Если вы застряли в 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) {
...

Это не супер читабельно, но он выполняет свою работу.

2 голосов
/ 18 июня 2013

Для меня это был ответ @ Лаки, а именно, строка

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

от Страница отладки Капитана

это решило мою проблему. У меня есть приложение на основе ApplicationContext, запускаемое из командной строки и, судя по ряду комментариев к SO, Spring по-разному подключает их к приложениям на основе MVC.

2 голосов
/ 02 января 2013

Значения свойств автопроводки в фасоль:

Большинство людей знают, что вы можете использовать @Autowired, чтобы сказать Spring, чтобы он вставлял один объект в другой, когда он загружает контекст вашего приложения. Менее известный фрагмент информации заключается в том, что вы также можете использовать аннотацию @Value для вставки значений из файла свойств в атрибуты компонента. см. этот пост для получения дополнительной информации ...

новые вещи весной 3.0 || значения bean для автопроводки || значения свойств автопроводки весной

1 голос
/ 20 октября 2016

Я думаю, что наиболее удобный способ внедрения свойств в 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).

Этот способ особенно полезен, если вам нужно более одного компонента на основе одной реализации.

Например, если мы определим еще один bean-компонент в 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) {
            ...
        }
    }
}
0 голосов
/ 19 апреля 2014

Использовать класс Spring "PropertyPlaceholderConfigurer"

Простой пример, показывающий, что файл свойств читается динамически как свойство бина

<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.mysql.jdbc.Driver

dev.app.jdbc.url = JDBC: MySQL: // локальный: 3306 / addvertisement

dev.app.jdbc.username = корень

dev.app.jdbc.password = корень

0 голосов
/ 13 марта 2013

Если вам нужно больше гибкости для конфигураций, попробуйте Settings4jPlaceholderConfigurer: http://settings4j.sourceforge.net/currentrelease/configSpringPlaceholder.html

В нашем приложении мы используем:

  • Предпочтения по настройке PreProd- и Prod-System
  • Параметры и переменные среды JNDI (JNDI перезаписывает параметры) для "mvn jetty: run"
  • Системные свойства для юнит-тестов (аннотация @BeforeClass)

Порядок по умолчанию, в котором ключ-значение-Источник проверяется первым, описан в:
http://settings4j.sourceforge.net/currentrelease/configDefault.html
Его можно настроить с помощью settings4j.xml (с точностью до log4j.xml) в вашем пути к классам.

Дайте мне знать ваше мнение: settings4j-user@lists.sourceforge.net

с уважением,
Harald

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...