org.springframework.beans.factory.BeanCreationException 尝试使用@Autowired 注释时

org.springframework.beans.factory.BeanCreationException while trying to use the @Autowired annotation

我正在创建一个使用 Controller、Service 和 Dao 的应用程序 classes.Service 并且 Dao 被创建为使用其实现 classes 实现的接口。我有一个名为 UserGroupController 的控制器 class 及其作为 UserGroupService 的服务。 .代码片段将是:

@Controller
@RequestMapping("module/usergroup")
public class UserGroupController 
{
    @Autowired
    UserGroupService userGroupService;

这个 @AutoWired 注释导致了这个问题,当我只删除那个注释时,如果我不使用那个注释,一切都可以在没有 exception.But 的情况下工作,每当我尝试访问我的服务的任何方法时 class,我得到一个空指针异常。

我的服务 class 如下所示:

@Repository("userGroupService")
public interface UserGroupService

它的实现是:

public class UserGroupServiceImpl implements UserGroupService
{
    @Autowired
    @Qualifier(value = "userGroupDao")
    UserGroupDao userGroupDao;

例外情况是:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userGroupController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.smartwcm.core.user.service.UserGroupService com.smartwcm.admin.user.controller.UserGroupController.userGroupService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.smartwcm.core.user.service.UserGroupService] 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:288)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1120)
    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.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:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:383)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
    at org.apache.catalina.core.StandardService.start(StandardService.java:525)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.smartwcm.core.user.service.UserGroupService com.smartwcm.admin.user.controller.UserGroupController.userGroupService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.smartwcm.core.user.service.UserGroupService] 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$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    ... 28 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.smartwcm.core.user.service.UserGroupService] 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.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:949)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:818)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:730)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
    ... 30 more

您需要将 @Service 注释添加到您的服务 class 实现中,以便它可以被 class 路径扫描拾取,添加到 Spring上下文,然后才有资格被自动装配。

package com.foo.bar.service;

@Service
public class UserGroupServiceImpl implements UserGroupService
{
    @Autowired
    @Qualifier(value = "userGroupDao")
    UserGroupDao userGroupDao;

还请确保如果您的服务 class 在包 com.foo.bar.service 中,则该包包含在 XML 的组件扫描包标签中。示例:

<context:component-scan base-package="com.foo.bar" />

为什么用@Repository注释呢?你可以将它用于你的 DAO 类。

(1) 用 @Service 代替

注释
@Service
public interface UserGroupService

(2) 或者您可以在 Spring 配置中将 UserGroupService 定义为一个 bean:

<bean id="userGroupService" class="com.your.package.UsergroupService" />

如果您将 @Repository 注释移至实现 class,它将起作用。请在下面找到示例代码:

接口class:

public interface Test {
    public void printMessage(String msg);
}

实施class:

@Repository("testService")
public class TestImpl implements Test {

    @Override
    public void printMessage(String msg) {
    System.out.println(msg);
    }

}

配置class:

@Configuration
@ComponentScan("com.praxissummit.eperf.api.domain.test")
public class TestConfig {

}

主要class:

public class Main {

    public static void main(String[] args) {
        ApplicationContext ctx = 
           new AnnotationConfigApplicationContext(TestConfig.class);
        ctx.getBean("testService", Test.class).printMessage("Hello world!!");
    }
}

如果我将 @Repository 注释移动到界面,spring 会抛出 No bean named 'testService' is defined

注意: 你实际上应该用 @Service 注释你的服务 class,而不是 @Repository

@Autowired 有时会令人困惑。您可以使用更通用的 java @Resource (jsr250) 注释。 @Resource 表示按名称给我一个已知资源。名称是从注解的setter或字段的名称中提取出来的,或者是从name-Parameter中提取出来的。 @Resource 有一个内置的回退,当按名称解析失败时会启动。在这种情况下,它会回退到 @Autowired 类型的分辨率。

@Controller
@RequestMapping("module/usergroup")
public class UserGroupController 
{
    @Resource(name="UserGroupService")
    UserGroupService userGroupService;

对于您的服务,您可以选择 @Component@Service

@Service
public interface UserGroupService { }

希望它能解决您的问题。查看 @Autowired@Resource 之间的区别以更加清楚。 @Resource vs @Autowired

@Service@Component 注释用于 spring 容器,它将动态创建对象。如果您使用 @Resource(前提是您在任何地方都使用 @Resource 为您的服务 class)

,您甚至可以选择退出上述注释

您应该遵循标准的存储库、服务、控制器模式。

@Controller : 控制器注解用于表示class是控制器。它包含为 http 请求提供服务的方法,请求映射在方法级别或 class 级别完成。
@Service : 用@Service 注释所有服务 classes。您所有的业务逻辑都将在 Service classes 中。控制器和 DAO 层将没有任何业务逻辑。
@Repository : 用@Repository 注释你所有的 DAO classes。您所有的数据库访问逻辑都应该在 DAO classes 中。

所以在你的情况下,注释应该是:

@Repository("userGroupDao")
public class UserGroupDaoImpl implements UserGroupDao

@Service("userGroupService")
public class UserGroupServiceImpl implements UserGroupService

@Controller
public class UserGroupController