2009-10-16 4 views
8

강력한 형식의 클래스로 속성 파일을 가져 오는 방법이 있습니까? 코드 생성기가 있지만 주석으로 처리하는 것이 훨씬 시원 할 것입니다.강력한 형식의 클래스로 Java .properties 파일

의미는 무엇입니까; 내가 그위한 오픈 소스 프로젝트를 시작해야하지 않을 경우

@properties(file="foo.properties") 
class foo { } 

와 어쩌면

foo.properties file 
keyFoo = valuefoo 
keyBar = valuebar 

class foo { 
    String getKeyFoo() { } 
    String getKeyBar() { } 
} 

이됩니까?

덧붙여 질문에 추가;

10 개 이상의 항목을 말하면서 foo.properties 파일이 있다고 가정하십시오. 이며 간단한 구성 파일로 사용된다고 생각하십시오. 필자가 생각하기에이 구성 항목은 관련 getXXX 메소드가있는 구성 클래스로 디자인의 다른 부분에 제공되어야합니다. 그런 다음 시스템의 나머지 부분은 키 이름을 처리하는 대신 제공되는 클래스를 통해 구성에 액세스하므로 구성이 오는 곳을 신경 쓰지 않아도됩니다. 그런 다음 호출자를 테스트하고 파일 시스템에 대한 종속성이 사라지면이 클래스를 mock으로 바꿀 수 있습니다. 한편으로는 에 모든 항목을 강력한 형식으로 입력하는 것이 좋습니다.

이 문제는 코드 생성 문제로 보이지만 런타임과 관련이 없습니다. 그러나 주석 대신 외부의 코드를 사용하는 코드 생성은 나에게 좋지 않은 것처럼 보였습니다. 어노테이션에 익숙하지는 않지만 (어쨌든 주석은 클래스를 McDowell 포인트로 생성 할 수 없다는 것을 명심해야한다.)

+1

어떤이의 사용 사례가 될 것이다는? 좋은 예가 될 것입니다. – Chii

답변

2

정적으로 입력 된 파일로 구성 할 때 somewhat similar project이 있습니다. 이 인터페이스를 선언 할 필요하지만 구현 자체를 채 웁니다 : (이것은 새로 만들 수 있지만) 클래스를 수정할 수 없습니다

public interface AppConfig extends Config { 
    long getTimeout(); 
    URL getURL(); 
    Class getHandlerClass(); 
} 
+0

링크가 죽었습니다 ... – Kukeltje

+0

OWNER 프레임 워크는이 구성을 제공합니다 (http://owner.aeonbits.org/ – vorburger

0

정적으로하고 싶다면 코드 생성 문제가 아주 쉽게 풀릴 수 있습니다 (파일의 각 항목에 대해 새로운 getXXX 메소드가 생성됩니다).

그러나 이것을 런타임에 원한다면 컴파일 타임에 존재하지 않는 코드를 참조하는 데 문제가 있습니다. 나는 그것이 끝날 수 있다고 생각하지 않는다.

(당신이 주석 방법에 의존하는 접근 방법 및 주석, 런타임에 생성 된 구현 인터페이스를 갖는 프로젝트 idead, 반대, 찾고 있다면, 수행 할 수 있습니다.)

+0

네, 할 수 있습니다 - 자바는 매우 역동적 인 언어이므로 자유롭게 수업을 나가고 수정할 수 있습니다. 문제는 "얼마나 많은 노력이 필요한가?"입니다. –

+0

물론, conf 파일에서 객체를 생성하는 것은 가능하지만, 미리 메소드를 알지 못한다면, 리플렉션이나 이와 같은 것에 의지하지 않고는 사용할 수 없으며, 이것은 훨씬 덜 흥미 롭습니다 . – penpen

+0

@Jonathan : IMO, 진짜 질문은 "요점은 무엇입니까?" 왜냐하면 @penpen은 반사 (또는 다른 생성 된 코드)를 사용하여 소설 getXXX 메소드 만 호출 할 수 있기 때문입니다. –

1

주석 처리 도구 (apt). 컴파일 시간에 클래스를 수정하려면 AST를 편집해야합니다 (Project Lombok). 가장 간단한 방법은 아마도 클래스를 생성 한 다음 생성 된 라이브러리를 다른 코드에 대한 종속성으로 사용하는 것입니다.

3

다양한 구성이 필요한 XML의 경우이를 달성 할 수있는 프레임 워크가 무수히 있습니다. Java와 번들 된 표준 JaxB하지만 하나의 라이너 xml 지속성 프레임 워크가 아닙니다 ...

문제는 속성 파일을 사용하는 것이 XML (또는 JSON, ...)보다 더 잘 작동한다는 것입니다 사소한 수업.클래스가 좀 더 복잡해지면 속성 파일이 악몽이 될 것입니다. 또 다른 문제점은 사소한 클래스에서 - XML과 속성간에 큰 차이가 없다는 것입니다.

즉, 프로젝트의 범위가 제한적이라는 의미입니다. 간단한 속성 파일이 많은 프로젝트에 유용합니다.

큰 응용 프로그램에서는 속성 파일의 강력한 형식 읽기가 간단한 factory-method를 사용하여 꽤 자주 수행됩니다.

Foo foo = Foo.loadFrom("foo.properties"); 

class Foo { 
    static Foo loadFrom(String fileName) { 
     Properties props = new Properties(); 
     props.load(...); 

     Foo foo = new Foo(); 
     foo.setKeyFoo(props.get("KeyFoo")); 
     ... 
     return foo; 
    } 
    ... 
} 
+0

참조). 런타임시 리플렉션을 사용하여 객체를 동적으로로드 할 수 있습니다. 주석을 읽을 수 있습니다 (클래스, 메소드 및 필드 객체) 및 속성을 동적으로 가져 오기/설정 (apache common-beans를 사용하면 도움이됩니다). 작은 설정이라도 간단하게 유지하십시오. 많은 구성을 위해 Xml은 구조, 유효성 검사 및 문서화 (XSD에서), ... – vdr

+0

+1 for JAXB. 제 구성으로 전환했습니다. 또한 내 config/state 구분을 지우도록 강요 받았다. –

1

JFig (추한 IMO), Commons Configuration 또는 EasyConf 같은 뭔가?

+0

OT : 재미있는 점 : 속성을 읽는 라이브러리가 많지만 순서가 지정된 반복을 제공하는 라이브러리가 없으므로 파일에 정의 된 순서대로 속성을 가져올 수 없습니다. 그래서 Properties를 확장하고 모든 Map 메소드를 ListOrderedMap에 위임했습니다. –

+0

JFig의 새로운 대안 : https://github.com/sofdes/config-generation-maven-plugin – user1016765

0

OP는 속성 파일을 Java API에 매핑하여 파일의 각 명명 된 속성이 API의 비슷한 명명 된 getter 메서드와 일치하도록하려고합니다. 나는 응용 프로그램이이 API를 사용하여 속성 이름 문자열을 사용할 필요없이 속성 값을 가져 오는 것으로 가정합니다.

개념적인 문제는 속성 파일이 근본적으로 정적으로 형식화 된 엔터티가 아니라는 것입니다. 누군가 속성 파일을 편집 할 때마다 새로운 속성을 추가 할 수 있으므로 속성 파일의 "유형"을 변경하고 해당 API의 서명을 암시 적으로 변경합니다. Java 응용 프로그램이 등록 정보 파일을로드 할 때 예기치 않은 속성이 없다는 것을 확인한 경우 명시 적 동적 유형 확인이 나타납니다. 예상치 못한 속성 (예 : 잘못된 이름)이 있는지 확인하지 않으면 오류가 발생합니다. 속성 값의 유형을 String이 아닌 다른 것으로 바꾸려면 상황이 더 복잡해집니다.

이 작업을 올바르게 수행 할 수있는 유일한 방법은 속성 이름과 속성 값 유형을 지정한 속성 파일의 스키마 개념을 만드는 것입니다. 그런 다음 사용자가 스키마와 충돌하는 특성을 추가 할 수 없도록하는 특성 파일 편집기를 구현하십시오.

이 시점에서 속성 파일 표현으로 XML을 사용하고 속성 파일을 편집하기위한 XML 스키마 기반 편집기 및 Java API에 속성 파일을 매핑하는 JAXP와 같은 더 나은 솔루션이 있다는 것을 인식해야합니다 .

+0

나는 정확히 당신이 의미하는 바를 얻지 못했고 따라서 파일의 "유형"을 변경합니다 ... "그러나 당신이 걱정하고있는 것은 파일의 다른 데이터 유형이라는 것 같군요? 그렇다면; 이 경우 반환 형식은 항상 String입니다. 따라서 파일에 새 항목을 추가하면 생성기에서 새 접근 자 메서드를 생성합니다. – erdogany

+0

@erdogany : 아니요. 변경되는 속성의 이름에 대해 이야기하고 있습니다. 질문을 읽으면 OP가 각 속성을 속성 이름에서 파생 된 고유 한 getter 메서드로 매핑하려고한다는 것을 알 수 있습니다. –

1

또 다른 방법은이 작업을 수행하는 데이터 바인딩 프레임 워크를 사용하는 것입니다. 예를 들어, Jackson JSON 프로세서는 다음과 같은 방식으로이 작업을 수행 할 수 있습니다.

ObjectMapper m = new ObjectMapper(); MyBean bean = m.convertValue (properties, MyBean.class); // (참고 : 트렁크의 최신 코드 필요, 그렇지 않으면 먼저 쓰는 것이 좋습니다.)

속성 맵의 항목이 논리 bean 속성과 일치하고 문자열 값을 기본 값과 일치시킬 수있는 한 작동합니다.

0

이 문제가 해결 될 것이라고 생각합니다. 작년에이 속성 프레임 워크에 대해 작성했습니다. 속성을로드하는 여러 가지 방법을 제공하고 강력하게 입력 할 수도 있습니다.

http://sourceforge.net/projects/jhpropertiestyp/

에서보세요이 열려 전래 완전히 소스 포지에서 내 간단한 설명입니다 여기에

을 문서화 :

JHPropertiesTyped will give the developer strongly typed properties. Easy to integrate in existing projects. Handled by a large series for property types. Gives the ability to one-line initialize properties via property IO implementations. Gives the developer the ability to create own property types and property io's. Web demo is also available, screenshots shown above. Also have a standard implementation for a web front end to manage properties, if you choose to use it. 

Complete documentation, tutorial, javadoc, faq etc is a available on the project webpage. 
관련 문제