Как читать значения из файла свойств?

133

Я использую пружину. Мне нужно прочитать значения из файла свойств. Это файл внутренних свойств, а не файл внешних свойств. Файл свойств может быть таким, как показано ниже.

some.properties ---file name. values are below.

abc = abc
def = dsd
ghi = weds
jil = sdd

Мне нужно прочитать эти значения из файла свойств не традиционным способом. Как этого добиться? Есть ли какой-нибудь последний подход к Spring 3.0?

user1016403
источник
7
Это не похоже на файл свойств .
Рагурам,
Если это файл свойств в смысле Java - да. В противном случае это настраиваемый формат файла, который нужно рассматривать по-другому (и вы не можете просто использовать строки в качестве значений свойств в Spring, если у них нет ключа).
Хауке Ингмар Шмидт,
3
«Не традиционным способом» - что вы имеете в виду?
Хауке Ингмар Шмидт,
я имею в виду использование аннотаций ... не конфигурацией xml ...
user1016403

Ответы:

196

Настройте PropertyPlaceholder в своем контексте:

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

Затем вы обращаетесь к свойствам вашего beans:

@Component
class MyClass {
  @Value("${my.property.name}")
  private String[] myValues;
}

РЕДАКТИРОВАТЬ: обновлен код для анализа свойства с несколькими значениями, разделенными запятыми:

my.property.name=aaa,bbb,ccc

Если это не сработает, вы можете определить bean-компонент со свойствами, ввести и обработать его вручную:

<bean id="myProperties"
      class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="locations">
    <list>
      <value>classpath*:my.properties</value>
    </list>
  </property>
</bean>

и фасоль:

@Component
class MyClass {
  @Resource(name="myProperties")
  private Properties myProperties;

  @PostConstruct
  public void init() {
    // do whatever you need with properties
  }
}
mrembisz
источник
Привет, mrembisz, Спасибо за ответ. Я уже настроил свойство-заполнитель для чтения значений из файла внешних свойств. но у меня есть один файл свойств внутри папки ресурсов. мне нужно читать и вводить. мне нужно ввести все значения в список. Спасибо!
user1016403
Отредактировано в соответствии с предложением @Ethan. Спасибо за обновление, не могу принять исходное редактирование, уже было слишком поздно.
mrembisz
2
В случае, когда вы имеете дело со значениями, разделенными запятыми, возможно, рассмотрите то, что предлагается здесь, с помощью EL: stackoverflow.com/questions/12576156/…
arcseldon
2
Как мы используем aaa? Неужели @Value(${aaa}) private String aaa;тогда можно System.out.println(aaa)???????
2
@ user75782131 Точнее учти @Value("${aaa}")цитаты. И да, вы можете распечатать его, кроме как в конструкторе, потому что конструктор выполняется до ввода значений.
mrembisz
48

Есть разные способы добиться того же. Ниже приведены некоторые часто используемые способы весной:

  1. Использование PropertyPlaceholderConfigurer

  2. Использование PropertySource

  3. Использование ResourceBundleMessageSource

  4. Использование PropertiesFactoryBean

    и многое другое ........................

Предполагая, что ds.typeэто ключевой момент в вашем файле свойств.


С помощью PropertyPlaceholderConfigurer

регистр PropertyPlaceholderConfigurer bean-

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

или

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations" value="classpath:path/filename.properties" ></property>
</bean>

или

@Configuration
public class SampleConfig {
 @Bean
 public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
  //set locations as well.
 }
}

После регистрации PropertySourcesPlaceholderConfigurerвы можете получить доступ к значению -

@Value("${ds.type}")private String attr; 

С помощью PropertySource

В последней весенней версии вам не нужно регистрироваться PropertyPlaceHolderConfigurerс @PropertySource, я нашел хорошую ссылку , чтобы понять версию compatibility-

@PropertySource("classpath:path/filename.properties")
@Component
public class BeanTester {
    @Autowired Environment environment; 
    public void execute() {
        String attr = this.environment.getProperty("ds.type");
    }
}

С помощью ResourceBundleMessageSource

Зарегистрировать Bean-

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
  <property name="basenames">
    <list>
      <value>classpath:path/filename.properties</value>
    </list>
  </property>
</bean>

Доступ к стоимости-

((ApplicationContext)context).getMessage("ds.type", null, null);

или

@Component
public class BeanTester {
    @Autowired MessageSource messageSource; 
    public void execute() {
        String attr = this.messageSource.getMessage("ds.type", null, null);
    }
}

С помощью PropertiesFactoryBean

Зарегистрировать Bean-

<bean id="properties"
      class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="locations">
    <list>
      <value>classpath:path/filename.properties</value>
    </list>
  </property>
</bean>

Экземпляр свойств провода в ваш класс -

@Component
public class BeanTester {
    @Autowired Properties properties; 
    public void execute() {
        String attr = properties.getProperty("ds.type");
    }
}
Сообщество
источник
Чтобы использовать PropertySourcesPlaceholderConfigurer, вы обычно должны установить местоположение или ресурс, иначе вы не сможете получить доступ к файлу свойств. Вы можете использовать, например, ClassPathResource generalProperties = new ClassPathResource ("general.properties");
M46,
43

В классе конфигурации

@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
   @Autowired
   Environment env;

   @Bean
   public TestBean testBean() {
       TestBean testBean = new TestBean();
       testBean.setName(env.getProperty("testbean.name"));
       return testBean;
   }
}
Мокшино
источник
В этом примере вы бы просто использовали другое app.propertiesпри тестировании в рабочей среде ? Другими словами, будет ли часть вашего процесса развертывания заменять app.propertiesпроизводственные значения?
Кевин Мередит
1
@KevinMeredith да, вы можете, просто разделите конфигурацию пружины с помощью аннотации профиля stackoverflow.com/questions/12691812/…
mokshino
@KevinMeredith мы используем папку вне развертывания войны: например, c: \ apps \ sys_name \ conf \ app.properties. Процесс развертывания упрощается и менее подвержен ошибкам.
jpfreire
27

Вот дополнительный ответ, который также очень помог мне понять, как это работает: http://www.javacodegeeks.com/2013/07/spring-bean-and-propertyplaceholderconfigurer.html

любые beanFactoryPostProcessor beans должны быть объявлены с помощью модификатора static

@Configuration
@PropertySource("classpath:root/test.props")
public class SampleConfig {
 @Value("${test.prop}")
 private String attr;
 @Bean
 public SampleService sampleService() {
  return new SampleService(attr);
 }

 @Bean
 public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
 }
}
Майкл Текур
источник
Нет необходимости явно регистрировать PropertySourcesPlaceholderConfigurerBean с помощью@PropertySource
@ dubey-theHarcourtians какую версию Spring (core) вы используете? если вы используете Spring Boot, вам вообще не нужно @PropertySource.
Michael Técourt
11

Если вам нужно вручную прочитать файл свойств без использования @Value.

Спасибо Локешу Гупте за хорошо написанную страницу: Блог

введите описание изображения здесь

package utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.io.File;


public class Utils {

    private static final Logger LOGGER = LoggerFactory.getLogger(Utils.class.getName());

    public static Properties fetchProperties(){
        Properties properties = new Properties();
        try {
            File file = ResourceUtils.getFile("classpath:application.properties");
            InputStream in = new FileInputStream(file);
            properties.load(in);
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
        }
        return properties;
    }
}
Джон
источник
Спасибо, в моем случае работает. Мне нужно прочитать свойства из статической функции.
Trieu Nguyen
6

Вам нужно поместить bean-компонент PropertyPlaceholderConfigurer в контекст вашего приложения и установить его свойство местоположения.

Подробности здесь: http://www.zparacha.com/how-to-read-properties-file-in-spring/

Возможно, вам придется немного изменить файл свойств, чтобы это работало.

Надеюсь, поможет.

instanceOfObject
источник
4

Другой способ - использовать ResourceBundle . Обычно вы получаете пакет, используя его имя без ".properties"

private static final ResourceBundle resource = ResourceBundle.getBundle("config");

И вы восстанавливаете любое значение, используя это:

private final String prop = resource.getString("propName");
Miluna
источник
0
 [project structure]: http://i.stack.imgur.com/RAGX3.jpg
-------------------------------
    package beans;

        import java.util.Properties;
        import java.util.Set;

        public class PropertiesBeans {

            private Properties properties;

            public void setProperties(Properties properties) {
                this.properties = properties;
            }

            public void getProperty(){
                Set keys = properties.keySet();
                for (Object key : keys) {
                    System.out.println(key+" : "+properties.getProperty(key.toString()));
                }
            }

        }
    ----------------------------

        package beans;

        import org.springframework.context.ApplicationContext;
        import org.springframework.context.support.ClassPathXmlApplicationContext;

        public class Test {

            public static void main(String[] args) {
                // TODO Auto-generated method stub
                ApplicationContext ap = new ClassPathXmlApplicationContext("resource/spring.xml");
                PropertiesBeans p = (PropertiesBeans)ap.getBean("p");
                p.getProperty();
            }

        }
    ----------------------------

 - driver.properties

    Driver = com.mysql.jdbc.Driver
    url = jdbc:mysql://localhost:3306/test
    username = root
    password = root
    ----------------------------



     <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:util="http://www.springframework.org/schema/util"
               xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

            <bean id="p" class="beans.PropertiesBeans">
                <property name="properties">
                    <util:properties location="classpath:resource/driver.properties"/>
                </property>
            </bean>

        </beans>
Санграм Бади
источник
добавить пояснение
HaveNoDisplayName
используя основной контейнер, вы не можете получить доступ к внешнему файлу свойств ресурса, поэтому вам нужно использовать контейнер j2ee, такой как ApplicationContext, и вам нужно использовать проверку уровня bean-компонентов, например xmlns, xmlns: util, xsi: schemaLocation, xmlns: xsi
Sangram Badi
0

Я рекомендую прочитать эту ссылку https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html из документации SpringBoot о внедрении внешних конфигураций. Они говорили не только о получении из файла свойств, но также о файлах YAML и даже JSON. Я нашел это полезным. Я надеюсь, что вы тоже.

theyCallMeJun
источник
0

Мне нужен служебный класс, которым не управляет spring, поэтому никаких аннотаций Spring, таких как @Componentи @Configurationт. Д., Но я хотел, чтобы класс читал изapplication.properties

Мне удалось заставить его работать, заставив класс знать о контексте Spring, следовательно, он знает Environmentи, следовательно, environment.getProperty()работает, как ожидалось.

Чтобы быть точным, у меня есть:

application.properties

mypath=somestring

Utils.java

import org.springframework.core.env.Environment;

// No spring annotations here
public class Utils {
    public String execute(String cmd) {
        // Making the class Spring context aware
        ApplicationContextProvider appContext = new ApplicationContextProvider();
        Environment env = appContext.getApplicationContext().getEnvironment();

        // env.getProperty() works!!!
        System.out.println(env.getProperty("mypath")) 
    }
}

ApplicationContextProvider.java (см. Spring получить текущий ApplicationContext )

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContextProvider implements ApplicationContextAware {
    private static ApplicationContext CONTEXT;

    public ApplicationContext getApplicationContext() {
        return CONTEXT;
    }

    public void setApplicationContext(ApplicationContext context) throws BeansException {
        CONTEXT = context;
    }

    public static Object getBean(String beanName) {
        return CONTEXT.getBean(beanName);
    }
}
Сида Чжоу
источник