2012-11-08 44 views
6

Tôi đã thử nghiệm bằng cách sử dụng Spring 3.1's bean definition profiles và các hạt lồng nhau. Tôi đã hy vọng rằng tôi có thể xác định đậu khác nhau tùy thuộc vào hồ sơ hoạt động. Hãy xem xét những điều sau nặng nề hơn ví dụ đơn giản như vậy mà bối cảnh mùa xuân của tôi chứa một cái gì đó giống nhưChế độ hiển thị hạt mùa xuân 3.1 sử dụng cấu hình định nghĩa bean

<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> 

tôi nhận được lỗi sau:

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

Tôi đã mong rằng chào đậu sẽ được xác định theo hồ sơ Maven hoạt động (trong trường hợp của tôi là prod hoặc dev). Tôi bắt đầu nghĩ rằng các cấu hình hoạt động trong mùa xuân (spring.profiles.active) có thể hoàn toàn không liên quan đến hồ sơ Maven.

Ai đó có thể giải thích tôi đang đi sai ở đâu? (Điều này thậm chí có thể sử dụng hồ sơ?).

Trả lời

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.

Đúng vậy, chúng không liên quan.

Đây là cách bạn có thể sửa chữa nó:

Hãy chắc chắn rằng web.xml mà bạn có trong src/main/webapp/WEB-INF/ thư mục có các thiết lập bối cảnh sau đây:

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

Và sau đó hãy chắc chắn rằng maven-war-plugin đã lọc léo trên cho số web.xml:

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

Và sau đó cuối cùng trong tiểu sử của bạn:

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

Bạn cũng có thể thêm một giá trị mặc định trong phần tài sản bình thường:

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

Vì vậy, nếu bạn chạy mà không có sự lựa chọn -P hồ sơ cá nhân dev mùa xuân sẽ được sử dụng.

Khi chạy mvn package, web.xml sẽ có giá trị chính xác cho spring.profile.active.

+0

Cảm ơn maba, có cách nào tốt đẹp để sử dụng spring.profiles.active bên ngoài ứng dụng web không? ví dụ. cho các bài kiểm tra đơn vị –

+1

Nếu bạn đang sử dụng thử nghiệm mùa xuân, bạn có thể sử dụng chú thích \ @ActiveProfiles cùng với các chú thích kiểm tra mùa xuân chuẩn khác (\ @ContextConfiguration, v.v ...). Tôi thường sử dụng điều này để thực hiện các kiểm tra cơ sở dữ liệu đối với các môi trường khác nhau. Tôi chạy một cái chống lại derby trong mục tiêu maven "test", và có một bộ khác cho oracle chạy cho mục tiêu maven "integration-test". Tôi tạo ra các lớp trừu tượng để xác định các bài kiểm tra và \ @ContextConfiguration, và mở rộng chúng, và sử dụng @ActiveProfiles để biến thành một bài kiểm tra đơn vị hoặc tích hợp. – Matt

+0

Cảm ơn, tôi đã bị mắc kẹt với trường hợp này và bạn đã lưu tôi: D –

2

Nhờ maba (câu trả lời tôi sẽ chấp nhận), tôi bắt đầu nghĩ về điều này theo một cách khác.

Tôi đã sửa đổi các mẹ đậu "nói" vì nó cần phải được khởi tạo lười biếng vì khi nó ban đầu được gặp bối cảnh đậu lồng nhau chưa tồn tại. Vì vậy, phiên bản mới bổ sung thêm một bean mới và thay đổi "nói" định nghĩa như vậy mà nó bây giờ trông giống như:

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

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

mới đậu InitProfile là một InitializingBean chịu trách nhiệm cho việc thiết lập các cấu hình hoạt động.

Nó chứa:

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(); 
     } 
    } 
} 

Sử dụng phương pháp này có những lợi thế nhất của việc có thể để thiết lập hồ sơ cá nhân mùa xuân tích cực sử dụng một tập tin thuộc tính classpath (điều này có thể khác nhau tùy thuộc vào hồ sơ Maven hoạt động của tôi). Tôi cũng thích cách tiếp cận này vì tôi có thể sử dụng nó cho cả ứng dụng web và các ứng dụng dòng lệnh.

Các vấn đề liên quan