2012-11-08 2 views
6

나는 Spring 3.1's bean definition profiles과 중첩 된 빈을 사용하여 실험 해왔다. 나는 활성 프로파일에 따라 다른 bean을 정의 할 수 있기를 희망했다.빈 정의 프로파일을 사용하는 Spring 3.1 빈 가시성

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'say' defined in class path resource [applicationContext.xml]: Cannot resolve reference to bean 'hello' while setting bean property 'hello'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'hello' is defined at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360) aJava Result: 1

내가 기대했던 안녕하세요 빈을 정의 할 것에 따른 : 단순화 된 예를 통해 크게 다음 사항을 고려 내 Spring 컨텍스트 나는 다음과 같은 오류가

<bean id="say" class="test.Say" p:hello-ref="hello"/> 

<beans profile="prod"> 
    <bean id="hello" class="test.Hello" p:subject="Production!"/> 
</beans> 

<beans profile="dev"> 
    <bean id="hello" class="test.Hello" p:subject="Development!"/> 
</beans> 

같은 등 포함 활성 Maven 프로필 (내 경우 또는 dev을 자극). 나는 스프링 활성 프로파일 (spring.profiles.active)이 Maven 프로파일과 완전히 관련이 없다고 생각하기 시작했다.

누군가 내가 잘못 가고 있다고 설명 할 수 있습니까? (이것은 프로필을 사용하여 가능합니까?).

답변

12

I was expecting that the hello bean would be defined according to the active Maven profile (in my case prod or dev). I'm starting to think that the Spring active profiles (spring.profiles.active) may be completely unrelated to Maven profiles.

사실, 관련이 없습니다. 다음

<context-param> 
    <param-name>spring.profile.active</param-name> 
    <param-value>${profileName}</param-value> 
</context-param> 

그리고 maven-war-plugin가 뒤집힌 필터링 있는지 확인합니다

것은 당신이 src/main/webapp/WEB-INF/ 폴더에있는 web.xml은 다음 상황에 맞는 설정이 있는지 확인하십시오 : 여기

당신이 그것을 해결할 수있는 방법입니다 web.xml의 경우 :

<plugin> 
    <artifactId>maven-war-plugin</artifactId> 
    <version>2.3</version> 
    <configuration> 
     <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors> 
    </configuration> 
</plugin> 

다음 프로필에서 마지막으로 :

<profiles> 
    <profile> 
     <id>dev</id> 
     <properties> 
      <profileName>dev</profileName> 
     </properties> 
    </profile> 
    <profile> 
     <id>prod</id> 
     <properties> 
      <profileName>prod</profileName> 
     </properties> 
    </profile> 
</profiles> 

또한 일반 속성 섹션에서 기본 값을 추가 할 수 있습니다 : 당신이 -P 옵션없이 실행하면 그래서 dev 봄 프로파일이 사용됩니다

<properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    <profileName>dev</profileName> 
</properties> 

합니다.

mvn package을 실행하면 web.xmlspring.profile.active에 올바른 값을 갖습니다.

+0

감사합니다. maba, 웹 응용 프로그램 외부에서 spring.profiles.active를 사용하는 좋은 방법이 있습니까? 예 : 단위 테스트 용 –

+1

스프링 테스트를 사용하는 경우 다른 표준 스프링 테스트 주석 (\ @ContextConfiguration, etc ...)과 함께 \ @ActiveProfiles 주석을 사용할 수 있습니다. 필자는 일반적으로 다른 환경에 대한 데이터베이스 테스트를 수행 할 때이를 사용합니다. 필자는 "테스트"목표에서 더비를 대상으로 실행하고 "통합 테스트"목표를 달성하기 위해 실행되는 또 다른 오라클 세트를 가지고 있습니다. 테스트를 정의하고 \ @ContextConfiguration을 정의하기 위해 추상 클래스를 생성하고이를 확장하고 @ActiveProfiles를 사용하여 유닛 또는 통합 테스트로 바꾼다. – Matt

+0

감사합니다. 나는이 경우에 붙어 있었고 당신은 나를 구해 주었다 : D –

2

maba (그 대답은 내가 받아 들일 것입니다) 덕분에, 나는 다른 방식으로 이것을 생각하기 시작했습니다. 이 처음 발견 될 때 중첩 된 콩 상황이 아직 존재하지 않기 때문에이 느리게 초기화 할 필요가 있기 때문에

나는 부모을 수정 한 "를 말한다". 그래서 새로운 버전은 새로운 빈을 추가하고 처럼 지금 보이는 정의하도록 "말"로 변경합니다

<bean class="test.InitProfile" p:profiles="dev"/> 

<bean id="say" class="test.Say" lazy-init="true" p:hello-ref="hello"/> 

새로운 InitProfile 콩

활성 프로파일을 설정하는 InitializingBean 표시 할 책임이있다.

이 포함

package test; 

import org.springframework.beans.BeansException; 
import org.springframework.beans.factory.InitializingBean; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.ApplicationContextAware; 
import org.springframework.context.ConfigurableApplicationContext; 
import org.springframework.util.StringUtils; 

public class InitProfile implements InitializingBean, ApplicationContextAware { 

    private ConfigurableApplicationContext ctx; 
    private String[] profiles; 

    public void setApplicationContext(ApplicationContext ac) throws BeansException { 
     ctx = (ConfigurableApplicationContext) ac; 
    } 

    public void setProfiles(String inprofiles) { 
     if (inprofiles.contains(",")) { 
      profiles = StringUtils.split(inprofiles, ","); 
     } else { 
      profiles = new String[]{inprofiles}; 
     } 
    } 

    public void afterPropertiesSet() throws Exception { 
     String[] activeProfiles = ctx.getEnvironment().getActiveProfiles(); 
     if (profiles != null && activeProfiles.length == 0) { 
      ctx.getEnvironment().setActiveProfiles(profiles); 
      ctx.refresh(); 
     } 
    } 
} 

이 방법을 사용하여 클래스 경로 특성 파일 사용중인 스프링의 프로파일을 설정할 수있는 장점 (이것은 내 활성 메이븐 프로파일에 따라 다를 수 있음)이있다. 웹 응용 프로그램과 명령 줄 응용 프로그램에 모두 사용할 수 있기 때문에이 방법이 마음에 듭니다.

관련 문제