Làm thế nào để đọc các giá trị từ tệp thuộc tính?


133

Tôi đang sử dụng mùa xuân. Tôi cần đọc các giá trị từ tập tin thuộc tính. Đây là tệp thuộc tính bên trong không phải là tệp thuộc tính bên ngoài. Tập tin thuộc tính có thể như dưới đây.

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

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

Tôi cần đọc các giá trị đó từ tệp thuộc tính không theo cách truyền thống. Làm thế nào để đạt được nó? Có cách tiếp cận mới nhất với mùa xuân 3.0 không?


7
Đây không giống như một tập tin thuộc tính .
Raghuram

Nếu nó là một tệp thuộc tính theo nghĩa Java - có. Mặt khác, nó là định dạng tệp tùy chỉnh cần được xử lý khác nhau (và bạn không thể chỉ sử dụng các dòng làm giá trị thuộc tính trong Spring nếu chúng không có khóa).
Hauke ​​Ingmar Schmidt

3
"Không phải theo cách truyền thống" - ý của bạn là gì?
Hauke ​​Ingmar Schmidt

ý tôi là sử dụng chú
thích..không

Câu trả lời:


196

Định cấu hình PropertyPlaceholder trong ngữ cảnh của bạn:

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

Sau đó, bạn tham khảo các thuộc tính trong đậu của bạn:

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

EDIT: đã cập nhật mã để phân tích thuộc tính với các giá trị được phân tách bằng dấu phẩy:

my.property.name=aaa,bbb,ccc

Nếu điều đó không làm việc, bạn có thể định nghĩa một bean với các thuộc tính, tiêm và xử lý nó bằng tay:

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

và đậu:

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

  @PostConstruct
  public void init() {
    // do whatever you need with properties
  }
}

Xin chào mrembisz, Cảm ơn bạn đã trả lời. tôi đã cấu hình giữ chỗ thích hợp để đọc các giá trị từ tệp thuộc tính bên ngoài. nhưng tôi có một tập tin thuộc tính trong thư mục tài nguyên. Tôi cần đọc và tiêm. tôi cần phải tiêm tất cả các giá trị vào danh sách. Cảm ơn!
user1016403

Được chỉnh sửa theo đề xuất của @Ethan. Cảm ơn đã cập nhật, không thể chấp nhận chỉnh sửa ban đầu, đã quá muộn.
mrembisz

2
Đối với trường hợp bạn đang xử lý các giá trị được phân tách bằng dấu phẩy, có thể xem xét những gì đang được đề xuất ở đây bằng cách sử dụng EL: stackoverflow.com/questions/12576156/
Kẻ

2
Làm thế nào để chúng ta sử dụng aaa? Có phải @Value(${aaa}) private String aaa;sau đó chúng ta có thể System.out.println(aaa)???????

2
@ user75782131 Chính xác hơn @Value("${aaa}"), hãy nhớ các trích dẫn. Và có, bạn có thể in nó trừ khi không có trong hàm tạo vì hàm tạo được thực thi trước khi các giá trị được chèn.
mrembisz

48

Có nhiều cách khác nhau để đạt được như nhau. Dưới đây là một số cách thường được sử dụng trong mùa xuân-

  1. Sử dụng PropertyPlaceholderConfigker

  2. Sử dụng PropertySource

  3. Sử dụng ResourceBundleMessageSource

  4. Sử dụng PropertiesFactoryBean

    và nhiều thứ khác nữa........................

Giả sử ds.typelà chìa khóa trong tập tin tài sản của bạn.


Sử dụng PropertyPlaceholderConfigurer

Đăng ký PropertyPlaceholderConfigurerđậu-

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

hoặc là

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

hoặc là

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

Sau khi đăng ký PropertySourcesPlaceholderConfigurer, bạn có thể truy cập giá trị-

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

Sử dụng PropertySource

Trong phiên bản mới nhất mùa xuân bạn không cần phải đăng ký PropertyPlaceHolderConfigurervới @PropertySource, tôi tìm thấy một tốt liên kết để hiểu phiên bản compatibility-

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

Sử dụng ResourceBundleMessageSource

Đăng ký Bean-

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

Giá trị truy cập-

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

hoặc là

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

Sử dụng PropertiesFactoryBean

Đăng ký Bean-

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

Ví dụ thuộc tính dây vào lớp của bạn-

@Component
public class BeanTester {
    @Autowired Properties properties; 
    public void execute() {
        String attr = properties.getProperty("ds.type");
    }
}

Để sử dụng PropertySourcePlaceholderConfigker, bạn thường phải đặt một vị trí hoặc tài nguyên nếu không bạn không thể truy cập tệp thuộc tính. Bạn có thể sử dụng, ví dụ ClassPathResource generalProperIES = new ClassPathResource ("general.properies");
M46

43

Trong lớp cấu hình

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

Trong ví dụ này, bạn chỉ cần sử dụng một cách khác app.propertiestrong thử nghiệm sản xuất v.? Nói cách khác, một phần của quy trình triển khai của bạn sẽ được thay thế app.propertiesbằng các giá trị sản xuất?
Kevin Meredith

1
@KevinMeredith có, bạn có thể, chỉ cần chia cấu hình mùa xuân của bạn bằng cách Hồ Sơ chú thích stackoverflow.com/questions/12691812/...
mokshino

@KevinMeredith chúng tôi sử dụng một thư mục bên ngoài cuộc chiến triển khai: như c: \ apps \ sys_name \ conf \ app.properies. Quá trình triển khai được đơn giản hóa và ít bị lỗi hơn.
jpfreire

27

Đây là một câu trả lời bổ sung cũng giúp tôi hiểu cách thức hoạt động của nó: http://www.javacodegeek.com/2013/07/spring-bean-and-propertyplacekeeperconfigurer.html

bất kỳ hạt BeanFactoryPostProcessor nào cũng phải được khai báo bằng công cụ sửa đổi tĩnh

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

Không cần phải đăng ký rõ ràng PropertySourcesPlaceholderConfigurerBean với@PropertySource

@ dubey-theHarcourtians bạn sử dụng phiên bản Spring (core) nào? nếu bạn đang sử dụng Spring Boot, bạn thậm chí không cần @PropertySourcehoàn toàn.
Michael Técourt

11

Nếu bạn cần đọc thủ công một tệp thuộc tính mà không cần sử dụng @Value.

Cảm ơn các trang được viết tốt bởi Lokesh Gupta: Blog

nhập mô tả hình ảnh ở đây

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

Cảm ơn, nó hoạt động cho trường hợp của tôi. Tôi cần đọc các thuộc tính từ hàm tĩnh.
Triệu Nguyễn


4

Một cách khác là sử dụng ResourceBundle . Về cơ bản, bạn nhận được gói sử dụng tên của nó mà không có '.properations'

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

Và bạn phục hồi bất kỳ giá trị nào bằng cách sử dụng này:

private final String prop = resource.getString("propName");

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>

thêm một số lời giải thích
HaveNoDisplayName

sử dụng bộ chứa lõi, bạn không thể truy cập tệp thuộc tính tài nguyên bên ngoài, vì vậy bạn cần sử dụng bộ chứa j2ee như ApplicationContext và bạn cần sử dụng xác thực cấp độ đậu như xmlns, xmlns: produc, xsi: lượcLocation, xmlns: xsi
Sangram Badi


0

Tôi muốn một lớp tiện ích không được quản lý bởi mùa xuân, vì vậy không có chú thích mùa xuân nào như @Component,@Configuration v.v. Nhưng tôi muốn lớp đó đọc từapplication.properties

Tôi quản lý để làm cho nó hoạt động bằng cách làm cho lớp nhận thức được Bối cảnh mùa xuân, do đó nhận thức được Environmentvà do đóenvironment.getProperty() hoạt động như mong đợi.

Để rõ ràng, tôi có:

ứng dụng

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 (xem Spring nhận ApplicationContext hiện tại )

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);
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.