Spring Boot Annotation @Autowired of Service 失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29808051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:31:34  来源:igfitidea点击:

Spring Boot Annotation @Autowired of Service fails

springspring-mvcannotationsspring-boot

提问by drunkenfist

I'm trying to use @Autowiredannotation for a Service class in Spring Boot application, but it keeps throwing No qualifying bean of typeexception. However, if I change the service class to a bean, then it works fine. This is my code:

我正在尝试@Autowired在 Spring Boot 应用程序中为 Service 类使用注释,但它一直抛出No qualifying bean of type异常。但是,如果我将服务类更改为 bean,则它可以正常工作。这是我的代码:

package com.mypkg.domain;
@Service
public class GlobalPropertiesLoader {

    @Autowired
    private SampleService sampleService;        
}

package com.mypkg.service;
@Service
public class SampleService{

}

And this is my SpringBoot class:

这是我的 SpringBoot 课程:

package com.mypkg;

import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableTransactionManagement
public class TrackingService {
    private static final Logger LOGGER = LoggerFactory.getLogger(TrackingService.class);

    static AnnotationConfigApplicationContext context;

    public static void main(String[] args) throws Exception {
        SpringApplication.run(TrackingService.class, args);
        context = new AnnotationConfigApplicationContext();
        context.refresh();
        context.close();

    }

}

When I try to run this, I get the following exception:

当我尝试运行它时,出现以下异常:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mypkg.service.SampleService] 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)}

But when I remove the @Serviceannotation from the SampleService class, and add it as a bean in my AppConfig class as below, it works fine:

但是,当我@Service从 SampleService 类中删除注释,并将其作为 bean 添加到我的 AppConfig 类中时,如下所示,它工作正常:

@Configuration
public class AppServiceConfig {

    public AppServiceConfig() {
    }

    @Bean(name="sampleService")
    public SampleService sampleService(){
        return new SampleService();
    }

}

The classes are in different packages. I am not using @ComponentScan. Instead, I'm using @SpringBootApplicationwhich does that automatically. However, I tried with ComponentScan as well but that didn't help.

这些类位于不同的包中。我没有使用@ComponentScan. 相反,我正在使用@SpringBootApplicationwhich 自动执行此操作。但是,我也尝试过 ComponentScan,但这没有帮助。

What am I doing wrong here?

我在这里做错了什么?

回答by Eddú Meléndez

You are using two ways to build a Spring's bean. You just need to use one of them.

您正在使用两种方法来构建 Spring 的 bean。您只需要使用其中之一。

  1. @Service over the POJO

    @Service
    public class SampleService
    
  2. @Bean in the configuration class which must be annotated with @Configuration

    @Bean
    public SampleService sampleService(){
        return new SampleService();
    }
    
  1. @Service 通过 POJO

    @Service
    public class SampleService
    
  2. 配置类中的@Bean,必须用@Configuration注解

    @Bean
    public SampleService sampleService(){
        return new SampleService();
    }
    

@Autowired is resolved by class type then @Bean(name="sampleService")is not needed is you have only one bean with that class type.

@Autowired 由类类型解析然后@Bean(name="sampleService")不需要,因为您只有一个具有该类类型的 bean。

EDIT 01

编辑 01

package com.example

包com.example

@SpringBootApplication
public class Application implements CommandLineRunner {

public static void main(String... args) {
    SpringApplication.run(Application.class);
}

@Autowired
private UserRepository userRepository;

@Autowired
private UserService userService;

@Override
public void run(String... strings) throws Exception {
    System.out.println("repo " + userRepository);
    System.out.println("serv " + userService);
}
}

package com.example.config

包 com.example.config

@Configuration
public class AppConfig {

@Bean
public UserRepository userRepository() {
    System.out.println("repo from bean");
    return new UserRepository();
}

@Bean
public UserService userService() {
    System.out.println("ser from bean");
    return new UserService();
}
}

package com.example.repository

包 com.example.repository

@Service
public class UserRepository {

@PostConstruct
public void init() {
    System.out.println("repo from @service");
}
}

package com.example.service

包 com.example.service

@Service
public class UserService {

@PostConstruct
public void init() {
    System.out.println("service from @service");
}

}

Using this code you can comment the AppConfig class and then you will se how UserRepository and UserService are autowired. After that comment @Service in each class and uncomment AppConfig and classes will be autowired too.

使用此代码,您可以注释 AppConfig 类,然后您将了解 UserRepository 和 UserService 是如何自动装配的。在每个类中注释 @Service 并取消注释 AppConfig 之后,类也将被自动装配。