0

我在一个项目中使用 Spring Data JPA (1.3.0.RELEASE) 和 Spring (3.2.2.RELEASE) 并面临一个奇怪的问题。我正在使用基于 xml 的配置,如下所述。

<context:annotation-config/>
<context:component-scan base-package="x.y.z.services"/> 

使用此配置扫描使用@Component、@Service 和@Named 注释修饰的类。

<jpa:repositories base-package="x.y.z.repo"/>

使用此配置扫描所有扩展 JpaRepository 的接口。这些接口通过以下方式注入到 Service 类中。

@Service
public class UserServiceImpl implements UserService {

    private UserRepository userRepository;

    @Inject
    public void setUserRepository(UserRepository userRepository) {
            this.userRepository = userRepository;
    }

    @Override
    public List<User> listUsers() {
            return userRepository.findAll();
    }
 }

此配置按预期工作,没有任何问题。但是当我添加以下配置时,我得到了 UserRepository 的 BeanCreationException。

    <bean id="securityRealm" class="x.y.z.Realm">
        <property name="userService">
            <bean class="x.y.z.services.UserServiceImpl"/>
        </property>
    </bean>

而且,这里是 Realm 和 UserRepository 的 Java 代码。

public class Realm extends AuthorizingRealm implements IRealm {

    private UserService userService;

    @Inject
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(
    AuthenticationToken token) throws AuthenticationException {
       return null;
    }

}

public interface UserRepository extends JpaRepository<User, String> {

}

根据上述配置,Spring 能够为 userService 创建 bean,但不能创建 UserRepository bean。

我可以通过扫描 xyzRealm 并使用 @Service 注释来装饰它来消除此错误。但这对我的应用程序来说将是一个非常大的限制和设计问题。

AFAICT,Spring 无法为 UserRepository 创建 bean,因为它的实现类不可用,必须由 jpa:repositories 配置提供。我可以看到 Spring 和 Spring Data JPA 没有协同工作。

有人可以帮我解决这个问题。下面是异常的堆栈跟踪。

    2013-04-30 21:44:04.745:INFO:/web:Initializing Spring root WebApplicationContext
    2013-04-30 21:44:07,009 [ERROR] [main] [org.springframework.web.context.ContextLoader] - Context initialization failed
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'shiroFilter' defined in class path resource [META-INF/Test-web/security-config.xml]: Cannot resolve reference to bean 'securityManager' while setting bean property 'securityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testShiroRealm': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: x.y.z.core.service.UserService x.y.z.core.security.testShiroRealm.userService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void x.y.z.core.service.internal.UserServiceImpl.setUserRepository(x.y.z.repo.UserRepository); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [x.y.z.repo.UserRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:329)
        at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:107)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1393)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1134)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
        at org.springframework.context.support.AbstractApplicationContext.registerBeantesttProcessors(AbstractApplicationContext.java:753)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
        at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:764)
        at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:406)
        at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:756)
        at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:242)
        at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1221)
        at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:699)
        at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:454)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
        at org.eclipse.jetty.server.handler.HandlerWrapper.doStart(HandlerWrapper.java:90)
        at org.eclipse.jetty.server.Server.doStart(Server.java:263)
        at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:59)
        at runjettyrun.Bootstrap.main(Bootstrap.java:80)
    ... 34 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void x.y.z.core.service.UserServiceImpl.setUserRepository(x.y.z.repo.UserRepository); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [x.y.z.repo.UserRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:601)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    ... 45 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [x.y.z.repo.UserRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:986)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:856)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:558)
    ... 47 more
4

1 回答 1

0

这是 Spring Data JPA 中的错误,现已修复。请查看 JIRA 问题以获得解决方案。

https://jira.springsource.org/browse/DATAJPA-335

于 2013-05-09T05:29:23.000 回答