2010-08-05 18 views
13

Một trong các thử nghiệm tích hợp của tôi sử dụng nhiều tệp ngữ cảnh mùa xuân. Dường như mùa xuân chỉ có autowires trong đậu từ bối cảnh đầu tiên và không phải là thứ hai. Có ai biết những gì tôi đang làm sai hoặc làm thế nào để làm việc xung quanh vấn đề?Làm cách nào để nhận lớp thử nghiệm tích hợp Spring to autowire bằng nhiều ngữ cảnh?

 
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { 
     "classpath:/META-INF/spring/applicationContext.xml", 
     "classpath:/META-INF/spring/applicationContext-security.xml"}) 
@Configurable 
public class UserDetailsServiceImplIntegrationTest { 

    @Autowired 
    UserDataOnDemand dod; 
    // @Autowired does not work for this bean from applicationContext-security.xml 
    UserDetailsService userDetailsService; 

    @Before 
    public void setup() { 
     dod.init(); 
     // workaround for autowiring problem 
     userDetailsService = (UserDetailsService)ctx.getBean("userDetailsService"); 
    } 

    @Test 
    public void testLoadUser() { 
     UserDetails ud = userDetailsService.loadUserByUsername("[email protected]"); 
     Assert.assertEquals("[email protected]", ud.getUsername()); 
    } 
} 

Tôi đang sử dụng Spring 3.0.3.

Đây là stack trace khi tôi bỏ ghi chú dòng @Autowired cho UserDetailsService:

 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'za.co.acme.app.security.UserDetailsServiceImplIntegrationTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.security.core.userdetails.UserDetailsService za.co.acme.app.security.UserDetailsServiceImplIntegrationTest.userDetailsService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.security.core.userdetails.UserDetailsService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1064) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374) 
    at org.springframework.beans.factory.wiring.BeanConfigurerSupport.configureBean(BeanConfigurerSupport.java:140) 
    at org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect.configureBean(AnnotationBeanConfigurerAspect.aj:59) 
    at org.springframework.beans.factory.aspectj.AbstractDependencyInjectionAspect.ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(AbstractDependencyInjectionAspect.aj:89) 
    at za.co.acme.app.security.UserDetailsServiceImplIntegrationTest.(UserDetailsServiceImplIntegrationTest.java:25) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513) 
    at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:202) 

bean chắc chắn là có kể từ khi "theo tên" công trình tra cứu, và nó là của đúng loại.

+0

mọi thứ trong nhật ký? – Bozho

+0

Tôi đã thêm một dấu vết ngăn xếp –

Trả lời

0

Tên đậu cho userDetailsService trong xml của bạn là gì? Bạn có thể cần phải thêm chú thích @Qualifier với tên bean và sau đó đặt một thẻ <qualifier> vào ngữ cảnh.

Hãy xem Spring's documentation về chủ đề.

+0

Tôi đã thử và cũng đã thử sử dụng @Resource mà không có bất kỳ may mắn nào. Tôi chỉ có một UserDetailsService đậu vì vậy cũng nên làm việc. Các thông báo lỗi chỉ ra rằng không có bean với đúng loại có thể được tìm thấy. –

7

Giải pháp thay thế là tạo một tệp cấu hình đơn mới (hãy gọi nó là "test-configuration.xml") bao gồm cả applicationContext.xml và applicationContext-security.xml. Sau đó, bạn có thể sử dụng các cấu hình này trong các thử nghiệm của mình.

thử configuration.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> 

    <import resource="classpath:/META-INF/spring/applicationContext.xml"/> 
    <import resource="classpath:/META-INF/spring/applicationContext-security.xml"/> 
</beans> 

UserDetailsServiceImplIntegrationTest.java:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration("/test-configuration.xml") 
@Configurable 
public class UserDetailsServiceImplIntegrationTest { 
... 
} 
3

Tôi có một thiết lập tương tự và nó làm việc tốt cho tôi.

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:/applicationContext-struts.xml", "classpath:/applicationContext.xml" }) 
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true) 
@Transactional 
public abstract class BaseTests { 

Tôi đoán là sự cố trong quá trình thiết lập dự án của bạn. Bạn có sử dụng Eclipse không? Nó có tải các tệp ngữ cảnh từ thư mục/bin hoặc từ thư mục/src không? Bạn đã loại trừ "applicationContext-security.xml" khỏi bản dựng chưa?

+0

Thực tế là tra cứu thủ công các tác vụ bean UserDetailsService cho biết rằng các tệp ngữ cảnh trong thực tế đang được tải ok. Nó chỉ là phần autowiring mà không phải là làm việc vì một lý do nào đó. –

+0

Cảm ơn bạn, điều này làm việc tốt cho tôi. – Mythul

1

Bạn cần phải thông báo cho Spring để thực hiện các chú thích đó. Trong tệp ngữ cảnh có liên quan, bạn nên thêm thông tin sau:

<context:annotation-config/> 

Bây giờ nó sẽ quét các chú thích đó. Xem tài liệu Mùa xuân trên Annotation-based configuration

Để hạn chế số lượng các lớp học nó cần để quét do đó bạn không không cần thiết quét gói không có autowiring, thêm này:

<context:component-scan base-package="org.example"/> 

Xem các tài liệu cho Auto-detecting components kiếm trên hơn rằng, cũng như các không gian tên XML bạn sẽ cần phải thêm để tham chiếu các thẻ đó.

0

Tôi có cùng một vấn đề. Có vẻ như có một UserDataOnDemand proxy thay vì UserDataOnDemand thực.

4

Tôi đã gặp phải vấn đề tương tự, giải pháp khắc phục được sự cố của tôi là chuyển bean hiển thị thông qua Giao diện. (tôi.e) Loại đậu tham chiếu của bạn phải là Giao diện thay vì lớp triển khai

Trong trường hợp của bạn, hãy thay đổi tham chiếu Lớp UserDetailsService cụ thể bằng giao diện của nó.

Ví dụ:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { 
     "classpath:/META-INF/spring/applicationContext.xml", 
     "classpath:/META-INF/spring/applicationContext-security.xml"}) 
@Configurable 
public class UserDetailsServiceImplIntegrationTest { 

    //modified code 
    @Autowired 
    IUserDetailsService userDetailsService; 

    //your test cases follows 

} 

LƯU Ý: Tôi biết điều này sẽ không là một giải pháp hợp lý, Nhưng chỉ cung cấp cho một thử, tôi lo lắng rất nhiều vì lỗi này cùng và cuối cùng là thay đổi tài liệu tham khảo của tôi và nó làm việc tốt. Hy vọng nó sẽ giải quyết vấn đề của bạn.

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