如何从 Spring Boot 应用程序中的所有子包中注册 bean?

Posted

技术标签:

【中文标题】如何从 Spring Boot 应用程序中的所有子包中注册 bean?【英文标题】:How to Register beans from all sub packages in Spring boot app? 【发布时间】:2019-07-04 23:29:01 【问题描述】:

我正在创建新的spring boot + jpa + thymeleaf 应用程序,我正在使用许多放在子包中的模块。我有像ge.my.project 这样的结构,我的主类与@SpringBootApplication 放在哪里,在这个package 下我有子包ge.my.project.daoge.my.project.servicege.my.project.controller 等等,我的豆子放在哪里。@SpringBootApplication仅扫描 base(ge.my.project) 包下的 bean,但我想从所有子包中扫描 beans

我尝试了很多变种来扫描sub packages

@ComponentScan(basePackages = "ge.my.project.controller","ge.my.project.service","ge.my.project.configuration")

@ComponentScan("ge.my.project.controller","ge.my.project.service","ge.my.proj ect.configuration")

@ComponentScan("ge.my.project.*")

但没有任何效果,当我尝试使用 @Autowired 注入 bean 时 我收到这样的错误Consider defining a bean of type 'ge.my.project.service.ServiceTypeService' in your configuration.

这是我的主要课程

package ge.my.project;

import ge.ufc.inhouseProjects.controller.ServiceTypeController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;


 @SpringBootApplication
//@ComponentScan(basePackages = "ge.my.project.controller","ge.my.project.service","ge.my.project.configuration")
@ComponentScan("ge.my.project.*")
@EntityScan("ge.my.project.entity")
@EnableJpaRepositories("ge.my.project.dao")
public class InhouseProjectsApplication 

public static void main(String[] args) 
    /*ApplicationContext applicationContext = */SpringApplication.run(InhouseProjectsApplication.class, args);



这是我的完整项目https://github.com/JavaGeoGroup/inhouseProjects.git

在 Spring Boot 应用程序中扫描所有项目 bean 的最清晰方法是什么?

【问题讨论】:

您不需要@ComponentScan 或所有其他注释。在这种情况下,只有@SpringBootApplication 就足够了。它会自动检测ge.my.project 中的任何内容,因为这是定义InhouseProjectsApplication 的地方,也是Spring Boot 开始扫描的地方。所以简而言之,删除所有注释,只留下@SpringBootApplication 同时查看您的存储库,您已经注释了接口,但是您应该注释实现类。 【参考方案1】:

您需要注释实现而不是接口。因此,在您的情况下,需要在 ServiceTypeDaoImpl-class 而不是 ServiceTypeDao-interface 上设置 @Service 注释。


您需要使用 @Component 注释或其子注释之一(如 @Repository、@Service、 @Controller,@Configuration

来自@Component 的javadoc:

 * Indicates that an annotated class is a "component".
 * Such classes are considered as candidates for auto-detection
 * when using annotation-based configuration and classpath scanning.
 *
 * <p>Other class-level annotations may be considered as identifying
 * a component as well, typically a special kind of component:
 * e.g. the @link Repository @Repository annotation or AspectJ's
 * @link org.aspectj.lang.annotation.Aspect @Aspect annotation.

您的代码示例的特定扩展: Spring bean 以一个小案例开头,所以你的接口“ServiceTypeDao”将被注册为“serviceTypeDao”,只要你不在“@Service”注解中设置具体的名称。

【讨论】:

我的 bean 上有所有这些注释,@Service 用于 my.project.service 包下的类 @Controller 用于 my.project.controller 类下的类等等,我没有错过这些注释,问题是别的东西。你可以看看我的项目,我链接了github 您需要注释实现而不是接口。我已经下载了你的例子,如果你用 @Service 注释你的 ServiceTypeServiceImpl 你会得到“ Started InhouseProjectsApplication in 4.928 seconds (JVM running for 5.373)”。

以上是关于如何从 Spring Boot 应用程序中的所有子包中注册 bean?的主要内容,如果未能解决你的问题,请参考以下文章

如何添加到 Thymeleaf/Spring Boot 发布请求中的子对象列表

thymeleaf spring boot templates 子文件夹中的视图

用于指定分发管理的自定义 spring boot 启动器

Spring Boot JPA多对多关系-Rest Web Service无法返回子对象

如何从 Spring Boot 项目中的子子表中检索数据?

“当前目录”中的 Spring Boot 外部属性文件被忽略