복붙노트

[SPRING] 프로그래밍 방식으로 Spring에서 속성 자리 표시자를 결정하는 방법

SPRING

프로그래밍 방식으로 Spring에서 속성 자리 표시자를 결정하는 방법

현재 스프링 3.1.0.M1을 기반으로하는 웹 애플리케이션을 기반으로 주석을 작성하고 있으며, 애플리케이션의 특정 위치에서 속성 자리 표시자를 해결하는 데 문제가 있습니다.

여기 이야기가 있습니다.

1) 내 웹 응용 프로그램 컨텍스트 (DispatcherServlet에 의해로드 됨)에서

mvc-config.xml :

<!-- Handles HTTP GET requests for /resources/version/**  -->
<resources mapping="/${app.resources.path}/**" location="/static/" cache-period="31556926"/> 

...

<!-- Web properties -->
<context:property-placeholder location="
    classpath:app.properties
    "/>

2) app.properties 내부에는 다음과 같은 2 개의 속성이 있습니다.

app.properties:

# Properties provided (filtered) by Maven itself
app.version: 0.1-SNAPSHOT
...

# Static resources mapping
app.resources.path: resources/${app.version}

3) JSP 2.1 템플릿에 JSP 사용자 정의 태그가 있습니다. 이 태그는 환경 설정, 앱 버전, 봄 테마 선택 등에 따라 전체 리소스 경로를 생성합니다. 맞춤 태그 클래스는 봄 : URL 구현 클래스를 확장하므로 일반적인 URL 태그로 간주 될 수 있지만 적절한 경로에 대한 추가 지식이 있습니다.

내 문제는 내 JSP 사용자 정의 태그 구현에서 $ {app.resources.path}를 올바르게 해석 할 수 없다는 것입니다. JSP 커스텀 태그는 Spring이 아닌 서블릿 컨테이너에 의해 관리되므로 DI에 참여하지 않아야한다. 그래서 나는 보통의 @Value ( "$ {app.resources.path}")를 사용할 수없고 Spring에 의해 자동으로 해결되도록 해준다.

내가 가진 모든 것은 웹 응용 프로그램 컨텍스트 인스턴스이므로 프로그래밍 방식으로 내 속성을 해결해야합니다.

지금까지 내가 시도 :

ResourceTag.java:

// returns null
PropertyResolver resolver = getRequestContext().getWebApplicationContext().getBean(PropertyResolver.class);
resolver.getProperty("app.resources.path");


// returns null, its the same web context instance (as expected)
PropertyResolver resolver2 = WebApplicationContextUtils.getRequiredWebApplicationContext(pageContext.getServletContext()).getBean(PropertyResolver.class);
resolver2.getProperty("app.resources.path");


// throws NPE, resolver3 is null as StringValueResolver is not bound
StringValueResolver resolver3 = getRequestContext().getWebApplicationContext().getBean(StringValueResolver.class);
resolver3.resolveStringValue("app.resources.path");


// null, since context: property-placeholder does not register itself as PropertySource
Environment env = getRequestContext().getWebApplicationContext().getEnvironment();
env.getProperty("app.resources.path");

그래서 지금 나는 그걸로 좀 붙어 있습니다. 내 자리 표시자를 해결할 수있는 능력이 문맥에 어딘가에 있다는 것을 알고 있습니다. 올바른 방법을 모릅니다. 확인을위한 도움이나 아이디어는 높이 평가됩니다.

해결법

  1. ==============================

    1.나는 context place holder의 내부 작업에 초점을 맞추기보다는 다음과 같이 새로운 util : properties를 간단히 정의 할 수 있다고 생각한다 :

    나는 context place holder의 내부 작업에 초점을 맞추기보다는 다음과 같이 새로운 util : properties를 간단히 정의 할 수 있다고 생각한다 :

    <util:properties id="appProperties" location="classpath:app.properties" />
    

    코드에서 다음과 같이 사용하십시오.

    Properties props = appContext.getBean("appProperties", Properties.class);
    

    또는 DI를 할 수있는 곳이면 어디든 좋아.

    @Value("#{appProperties['app.resources.path']}")
    
  2. ==============================

    2.Spring 3.0.3 이후에는 appContext.getBeanFactory (). resolveEmbeddedValue ( "$ {prop}") 호출을 사용하는 다른 게시물에서 언급 한 것과 같은 방식으로 작동하는 EmbeddedValueResolverAware가 있습니다.

    Spring 3.0.3 이후에는 appContext.getBeanFactory (). resolveEmbeddedValue ( "$ {prop}") 호출을 사용하는 다른 게시물에서 언급 한 것과 같은 방식으로 작동하는 EmbeddedValueResolverAware가 있습니다.

    문제를 해결하려면 다음을 수행하십시오.

    그런 다음 bean은 필요한 특성을 검색하기 위해 ApplicationContext에 의존 할 필요가 없다.

  3. ==============================

    3.버전 3.0 이후, Spring은 beanFactory에 문자열 분석기의리스트를 유지한다. 다음과 같이 사용할 수 있습니다.

    버전 3.0 이후, Spring은 beanFactory에 문자열 분석기의리스트를 유지한다. 다음과 같이 사용할 수 있습니다.

    String value = appContext.getBeanFactory().resolveEmbeddedValue("${prop}");
    

    javadoc에서는 주석 속성과 같은 내장 된 값을 분석하는 방법으로이 방법을 설명하므로 어쩌면 우리는 그 사용법을 우회하고 있지만 작동합니다.

  4. ==============================

    4.하나의 옵션은 ConfigurableEnvironment에 PropertySource (여기에서 MapPropertySource)를 추가하여 속성을 확인하도록 요청하는 것입니다.

    하나의 옵션은 ConfigurableEnvironment에 PropertySource (여기에서 MapPropertySource)를 추가하여 속성을 확인하도록 요청하는 것입니다.

    public class Foo {
    
        @Autowired
        private ConfigurableEnvironment env;
    
        @PostConstruct
        public void setup() {
            env.getPropertySources()
               .addFirst(new MapPropertySource("my-propertysource", 
                   ImmutableMap.<String, Object>of("your.property.name", "the value")));
            env.resolvePlaceholders("your.property.name");
        }
    }
    

    선택적으로 Foo 클래스에 @Configuration 주석을 달아 XML에 대한 프로그래밍 방식 구성 기능을 활용할 수 있습니다.

  5. ==============================

    5.가능한 한 해결책이 더 있습니다. 태그 클래스를 AspectJ를 통해 @Configurable하고 컴파일 타임이나 로딩 타임을 가능하게하는 방법이 있습니다. 그런 다음 커스텀 태그에서 일반적인 @Value 주석을 사용할 수 있습니다. 그러나 정말로, 나는 단지 두 개의 학급 때문에 짜기 기반을 설정하고 싶지 않다. 여전히 ApplicationContext를 통해 자리 표시자를 해결하는 방법을 찾고 있습니다.

    가능한 한 해결책이 더 있습니다. 태그 클래스를 AspectJ를 통해 @Configurable하고 컴파일 타임이나 로딩 타임을 가능하게하는 방법이 있습니다. 그런 다음 커스텀 태그에서 일반적인 @Value 주석을 사용할 수 있습니다. 그러나 정말로, 나는 단지 두 개의 학급 때문에 짜기 기반을 설정하고 싶지 않다. 여전히 ApplicationContext를 통해 자리 표시자를 해결하는 방법을 찾고 있습니다.

  6. from https://stackoverflow.com/questions/5172392/how-to-programmatically-resolve-property-placeholder-in-spring by cc-by-sa and MIT license