source

Spring XML 컨텍스트에서 조건부 리소스 가져오기를 수행하는 방법은 무엇입니까?

manysource 2023. 8. 23. 21:52

Spring XML 컨텍스트에서 조건부 리소스 가져오기를 수행하는 방법은 무엇입니까?

자식 Spring XML 컨텍스트의 가져오기를 "동적으로"(즉, 구성 파일에 정의된 속성을 기반으로 함) 설정/해제할 수 있는 기능이 필요합니다.

저는 다음과 같은 것을 상상합니다.

<import condition="some.property.name" resource="some-context.xml"/>

속성이 확인되는 위치(부울 위치)와 true인 경우 컨텍스트를 가져오고 그렇지 않은 경우 컨텍스트를 가져옵니다.

지금까지 제가 조사한 내용 중 일부는:

  • 사용자 지정 네임스페이스 처리기(및 관련 클래스)를 작성하여 사용자 지정 요소를 사용자 지정 네임스페이스에 등록할 수 있습니다.예:<myns:import condition="some.property.name" resource="some-context.xml"/>

    이 접근 방식의 문제는 Spring의 전체 리소스 가져오기 논리를 복제하고 싶지 않다는 것이며, 이를 위해 무엇을 위임해야 하는지 명확하지 않다는 것입니다.

  • 오버라이드DefaultBeanDefinitionDocumentReader"가져오기" 요소의 구문 분석 및 해석의 동작을 확장합니다(이는 그곳에서 발생합니다).importBeanDefinitionResource방법)을 선택합니다.하지만 이 연장을 어디서 등록할 수 있는지 잘 모르겠습니다.

Spring 4 이전에는 표준 Spring 구성 요소를 사용할 수 있는 가장 가까운 값은 다음과 같습니다.

<import resource="Whatever-${yyzzy}.xml"/>

어디에${xyzzy}시스템 속성에서 속성을 보간합니다.(로딩 프로세스를 시작하기 전에 다른 위치의 속성을 시스템 속성 개체에 추가하는 컨텍스트 로더 클래스의 해키한 사용자 정의 버전을 사용합니다.)

하지만 불필요한 것들을 많이 수입하는 것을 피할 수도 있고... 필요한 콩만 인스턴스화되도록 다양한 속임수를 사용할 수도 있습니다.이러한 기술에는 다음이 포함됩니다.

  • 자리 표시자 및 재산 대체
  • 새로운 Spring 표현 언어를 사용하여 다른 콩을 선택하는 것,
  • 대상 이름에 자리 표시자가 있는 별칭입니다.
  • 게으른 콩 초기화 및
  • 강낭콩 공장

이제 스프링 4를 사용하여 완전히 가능합니다.

기본 응용프로그램 컨텐츠 파일

<bean class="com.example.MyConditionalConfiguration"/>

그리고 내 조건부 구성은 다음과 같습니다.

@Configuration
@Conditional(MyConditionalConfiguration.Condition.class)
@ImportResource("/com/example/context-fragment.xml")
public class MyConditionalConfiguration {
    static class Condition implements ConfigurationCondition {
         @Override
         public ConfigurationPhase getConfigurationPhase() {
             return ConfigurationPhase.PARSE_CONFIGURATION;
         }
         @Override
         public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
             // only load context-fragment.xml if the system property is defined
             return System.getProperty("com.example.context-fragment") != null;
         }
    }
}

그런 다음 마지막으로 /com/example/context-fragment.xml에 포함할 빈 정의를 넣습니다.

@Conditional은 JavaDoc 참조

앞서 언급했듯이 Spring 3.1+를 사용하는 경우 프로필을 사용하여 쉽게 수행할 수 있습니다.

<!-- default configuration - will be loaded if no profile is specified -->
<!-- This will only work if it's put at the end of the configuration file -->
<!-- so no bean definitions after that -->
<beans profile="default">
    <import resource="classpath:default.xml" />
</beans>
<!-- some other profile -->
<beans profile="otherProfile">
    <import resource="classpath:other-profile.xml" />
</beans>

다른 프로파일은 예를 들어 쉽게 활성화할 수 있습니다.

mvn install -Dspring.profiles.active=otherProfile

테스트에서 다른 프로필을 사용하는 경우 추가하십시오.-DforkMode=never한 VM하기 위해 매개 인 "VM"을 사용합니다. 따라서 매개 변수spring.profiles.active길을 잃지 않을 것입니다

Spring 3.1.x에서는 bean 프로파일을 사용하여 조건부 리소스 가져오기 및 bean 인스턴스화를 수행할 수 있습니다.이전 버전을 사용하고 있다면 당연히 도움이 되지 않습니다 :)

참고로 Robert Maldon은 http://robertmaldon.blogspot.com/2007/04/conditionally-defining-spring-beans.html 에서 콩의 조건부 정의를 달성하는 방법을 설명합니다.여기에 복사하기에는 좀 깁니다(게다가 어쨌든 그의 글을 복사해서 붙이면 안 될 것 같습니다).

이 접근 방식의 최종 결과는 다음과 같습니다.

<condbean:cond test="${some.property.name}">
  <import resource="some-context.xml"/>
</condbean:cond>

Stephen C의 해결책처럼 그렇게 간단하지는 않지만 훨씬 더 강력합니다.

Spring 3.0에 대해 고려해야 할 또 다른 사항:

 <alias name="Whatever" alias=""Whatever-${yyzzy}" />

${xyzzy}시스템 속성에서 속성을 보간합니다.

다른 옵션은 /conf 폴더에 있는 modules-config.xml 파일을 앱에서 로드하고 설치/구성 단계에서 편집하여 로드할 모듈의 주석을 제거하는 것입니다.

이것이 제가 여러 통합 모듈의 컨테이너 역할을 하는 웹 애플리케이션과 함께 사용하는 솔루션입니다.웹 애플리케이션은 모든 다른 통합 모듈과 함께 배포됩니다.modules-config.xml "tomcat" /conf 파일은 conf 파일 catalina.properties/common.의 파일입니다.웹 앱 에 "webapp-config.xml"이 .<import resource="classpath:/modules-config.xml"/>그것을 싣기 위해.

contextInitialized(javax.servlet)를 재정의할 수 있습니다.사용자 자신의 ContextLoaderListener에서 ServletContextEvent 이벤트)를 실행하고 super.contextInitialized(이벤트) 앞에 필요한 시스템 속성을 설정합니다.

package com.mypackage;
import org.springframework.web.context.ContextLoaderListener;
public class MyContextLoaderListener extends ContextLoaderListener {
    public void contextInitialized(javax.servlet.ServletContextEvent event) {
        System.setProperty("xyz", "import-file-name.xml");
        super.contextInitialized(event);
    }
}

그리고 contextLoaderListener를 web.xml의 MyContextLoaderListener로 바꿉니다.

<listener>
    <listener-class>com.mypackage.MyContextLoaderListener</listener-class>
</listener>

이제 spring.xml에서 사용할 수 있습니다.

<import resource="${xyz}" /> 

이것이 도움이 되길 바랍니다.

언급URL : https://stackoverflow.com/questions/3035630/how-to-achieve-conditional-resource-import-in-a-spring-xml-context