2009-08-04 3 views
11

몇 가지 클래스가 있는데 일부 속성 파일을로드해야하며이를 수행하는 가장 좋은 방법이 무엇인지 궁금합니다. 속성은 각 클래스에 파일 이름을 다음 사람이 등록 정보 파일의 이름을 변경하기로 결정하면 문제가 될 수있는하는 FileInputStream에서로드 할 Properties 클래스를 사용속성을로드하는 가장 좋은 전략은 무엇입니까?

  • 하드 코딩 : 나는 두 가지 기본 방법을 생각 , 코드에서 하드 코딩됩니다.

    public class A { 
        public A() { 
         Properties p = new Properties().load(
           new FileInputStream("properties/Aconfig.properties")); 
         String value = p.getProperty("key", ""); 
        }   
    } 
    
  • 클래스 이름 주어진 클래스와 같은 이름을 가진 속성 파일을로드하는 방법을 만들기

    . 이 방법은 속성 파일 이름을 하드 코드 할 필요가 없지만 파일 명명에 규칙을 따라야하므로 혼동이 발생할 수 있습니다. 그러나

public class A { 
    public A() { 
     Properties p = PropertiesHelper.loadFromClassName(A.class.getName()); 
     // here, we **assume** that there is a A.properties file in the classpath. 
    } 
} 
, 거기에 많은 다른 더 우아한 방법, 그리고 내가이 질문을 제기 그 이유는 수 있습니다 : 자바에서로드 특성 파일에 대한 가장 좋은 방법은 무엇 I)?; ii) 직업을 돌보는 도우미 클래스를 사용합니까?; iii) (코드에서) 일반적으로 등록 정보 파일을로드하는 위치는 어디입니까?

또한 클래스가 속성을 "자동로드"해도 괜찮습니까? 아니면 필요한 인수를 생성자에 전달해야합니까? 인수를 전달하는 문제는 일부 클래스 (통계 모델의 매개 변수를 나타내는 ~ 20)에 너무 많은 방법이 있다는 것입니다.

답변

7

최고의 방법은 dependency injection 용기의 어떤 종류를 사용하는 것 - 예를 Spring Framework 또는 Google Guice을 위해.

모든 종류의 문제를 해결합니다. 특정 속성 파일 이름에 클래스를 묶지 않아도 해당 클래스 내에서 해당 속성을로드하는 것에 대해 걱정할 필요가 없으며 가능한 예외를 처리 할 필요가 없습니다. 명령 행 인수 (또는 시스템 특성)로서 30 개의 특성 파일 이름을 전달하십시오.

또한 속성 로딩 외에도 많은 다른 많은 것들에 도움이됩니다 .- 그것을 시도해보십시오. 그러면 어떻게 살아 왔는지 궁금 할 것입니다.

업데이트 : 덧붙여 말하자면, your other question은 Spring이 처리 할 것 중 하나입니다.

업데이트 # 2 : 방금 ​​내가 already tried to push Spring을 알게되었습니다 :-) 자신을 반복 할 위험이 있으므로 Spring은 여기에서 추상화에 도움이 될 것입니다. 속성 파일에 무엇을 저장했는지에 따라 구성 파일을 필요로하지 않을 수도 있고 (구성을 처리하는 경우) 또는 리소스 번들 또는 이와 유사한 것이면 매우 좋은 API를 사용할 수 있습니다.

+0

예 :), 특정 문제에 대해 SF를 사용하려고합니다. 그러나이를 위해 속성 파일을 모든 사람 (컴퓨터 프로그래머가 아님)이 쉽게 구성/변경할 수 있기를 원하므로 간단한 "키 = 값"기반 파일 스키마가 필요합니다. –

+0

당신은 여전히 ​​그것을 할 수 있습니다. Spring은 매우 훌륭한 리소스 추상화 레이어를 가지고 있습니다 : http://static.springsource.org/spring/docs/2.5.x/reference/resources.html 그러면 클래스를 묶지 않고 "있는 그대로"의 속성 파일을 처리 할 수 ​​있습니다. 그들에게 직접. – ChssPly76

+0

흠, 나는 그것에 대해 읽을 것입니다. 고마워요. 내가 안에 요소를 언급하고 있다고 생각했습니다. 귀하의 질문에 관해서는 기본적으로 모델 매개 변수를 많이 저장합니다 (예 : numberOfTrials = 50 등). –

0

이전에는 시스템 속성을 통해 속성을로드했습니다. 파일 이름은 시스템 속성을 통해 전달되고 그 파일을로드합니다. 시스템 속성이 설정되지 않은 경우 사용할 기본 이름이 있습니다. 파일이 존재하지 않으면, 당신은 그곳에서해야 할 일을 결정할 필요가 있습니다.

좋은 점은 표준이 있지만 명령 줄 인수를 사용하여 위치/이름을 재정의 할 수 있다는 것입니다.

그래도 내 2 센트.

1

여러 개의 속성 파일을 하나의 Properties 개체에로드하고 차례대로로드하십시오. 이 체계는 맵핑이 여러 지점에서 대체 될 수있는 기본값을 갖도록합니다.

1

파일 이름은 응용 프로그램의 명령 줄에서 쉽게 전달할 수 있습니다. 이것은 -D flag을 사용하여 arg to the main method (메인 클래스 이름 다음) 또는 속성 (aperkins가 암시하는 것처럼, 나는 믿는다) 중 하나로서 수행 될 수 있습니다.

+0

나는 그것을 알고 있지만 웹 환경에서도 잘 작동 할 수있는 응용 프로그램이 필요합니다. 또한, 나는 많은 파일 이름이 전달되어야하고, 나는 그 메소드를 사용하여 새로운 스크립트를 만들 때마다 run.sh (또는 이와 유사한) 스크립트를 변경해야 할 필요가있다. –

+0

파일 이름을 하드 코딩 한 경우 비슷한 위치에있게됩니다. 명령 줄에 필요한 구성 파일 목록이 들어있는 파일 이름을 가질 수 있습니다. – akf

0

파일 및 파일 시스템 관련 경로를 사용하지 않는 것이 좋습니다. 이유는 다음과 같습니다. - 런타임과 테스트 시간 사이에 클래스 로더를 분리하여 코드를 테스트 할 수있게 해줍니다. 보통 괜찮은 빌드 시스템에 의해 수행됩니다. - 이렇게하면 클래스 경로를 사용하는 것이 좋습니다. 코드 위치가 독립적이며 OS 문제를 무시할 수 있습니다. 코드가 독립 실행 형 응용 프로그램이나 컨테이너 (경량, 서블릿, 응용 프로그램 서버 등)와 동일하게 작동합니다.

로케일을 인식하는 멋진 추가 기능이있는 PropertyResourceBundle에서 다른 로켈 설정으로 다른 속성을 정의 할 수 있습니다. Locale은 l10n 또는 i18n 문제와 독립적으로 매개 변수화를 제공하기 위해 남용 될 수 있습니다 (예 : 나 자신의 Locale 인스턴스를 생성하여 로더에 전달할 수 있기 때문에 프로젝트에 "windows"와 "linux"로케일을 사용했습니다.

 Properties prop = Properties.load(getClass().getResourceAsStream("/myprops")); 

HTH를 : 당신이 입력 스트림로부터 속성을로드 할 수 있습니다

또는

아니면 그냥 경로를 직접 구성 할 수 있습니다 ....

+0

봄은 좋지만 이러한 단순한 기능에 대해서는 약간 과장 될 수 있습니다. 당신은 DI보다 조금 더 가벼운 PicoContainer를 보게 될 것입니다. – insitu

+0

나는 당신의 질문을 간과해서 부적절한 대답을했습니다. 특정 사건에서 이미 수행 한 작업은 루트 등록 정보 파일에로드 할 등록 정보를 호스트하는 것입니다. 어쨌든이 정보는 코드에 하드 코드되거나 구성 파일에 저장되어야합니다. 모든 것에 동일한 메커니즘을 사용하는 것이 더 좋습니다 ... 그러나 속성이 클래스 이름과 연결되어 있으면 두 번째 솔루션을 사용하는 것이 좋지만 기본 소스 트리 외부에서 쉽게 편집 할 수 있도록 속성을 저장하고 추가하십시오 런타임시 classpath에 있습니다. – insitu

관련 문제