其他包中的@RestController 不起作用

@RestController in other package doesn't work

我从学习 Spring 开始,我创建了创建数据库的基本项目,插入值,然后在网络浏览器中打印它。 我的问题是,当我在同一个包中有 RestController 时,就像 main class - 没问题,但我想将它分发到其他包,当我创建新包时,移动 RestController 它不起作用。让我们来解释一下:

我的项目看起来像:

          |-Springtestv_01
            |-src/main/java
              |--com.person <-- it's a main package
                 |-Main.java
                 |-Person.java
                 |-PersonLineRunner.java
                 |-PersonRepository.java
                 |-PersonController.java
              |-com.controller <-- second package, I want put here PersonController.java
            |-src/main/resources
              |-data.sql
            pom.xml

我的控制器看起来:

@RestController
public class PersonController {

    @Autowired PersonRepository personRepository;

    @RequestMapping("/persons")
    Collection<Person> persons(){
        return this.personRepository.findAll();
    }
}  

当一切都在 com.person 包中时,我在网络浏览器 http://localhost:8080/persons 中编写并且它工作正常...... 但我想将 PersonController.java 移动到 com.controller 包,当我移动它时,我的网络浏览器称我为

There was an unexpected error (type=Not Found, status=404). No message available

而且我不知道应该如何修复它。也许我应该改变我的 pom.xml ??

我的pom.xml长得像

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.person</groupId>
    <artifactId>person</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>SpringTest_v0_1</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.0.BUILD-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.h2database</groupId><artifactId>h2</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>
                spring-boot-starter-data-elasticsearch
            </artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

</project>

自动生成,我只写一个依赖

    <dependency>
        <groupId>com.h2database</groupId><artifactId>h2</artifactId>
    </dependency>

使用 @SpringBootApplication 注释等同于使用 @Configuration@EnableAutoConfiguration@ComponentScan

来自文档:

ComponentScan configures component scanning directives for use with @Configuration classes. Provides support parallel with Spring XML's element.

One of basePackageClasses(), basePackages() or its alias value() may be specified to define specific packages to scan. If specific packages are not defined scanning will occur from the package of the class with this annotation.

您可以照原样移动它,也可以在 @ComponentScan 中指定 basePackages

使用基础包:

@ComponentScan(basePackages = { "com.person","com.controller"} )

我们可以使用@ComponentScan (basePackages = {"include your package name here"}).

此外,如果您有一些通用的包命名格式,那么我们可以只包含包名称的通用部分 *,例如 @ComponentScan(basePackages = { "com.*"},这样所有具有该通用包名称的包都会被扫描.

我遇到了同样的问题,这里提供的答案对我有用,但我不得不添加另一个 spring 注释,并且在处理大量存储库的情况下它更通用。 我们有以下结构:

 |-src/main/java
    |--com.person 
       |--repositories
       |--controllers
       |--...

这应该添加到主程序中

@SpringBootApplication(scanBasePackages = {"com.person"}) 
@EnableMongoRepositories(basePackages = "com.person.repositories")
public class MainDemoApplication { //
}

我遇到了同样的问题,但突然发现我的 Application.java class(带有 main 方法和 @SpringBootApplication 注释的 class)位于不同但与 @Controller 并行的包中 class。

问题是 Application.java class 应该在所有其他包中或在所有其他包之上,然后我们不需要任何 @ComponentScan 并且所有 bean 将被自动扫描。例如:如果 Application.java 位于 com.person 并且所有应用程序 bean 位于 com.person,那么它将在没有 @ComponentScan 的情况下工作。

作为一直为这个问题苦苦挣扎的人,如果您发现提供的解决方案不起作用。
请检查是否直接将源文件放在根目录下,例如
src\main\java\xxx.java

对项目有负面影响,但我不知道根本原因。无论如何,

请至少将源文件放入一个自建包中,例如: src\main\java\pack1\xxx.java

重试其他设置。它确实解决了我的问题。

你只需要在@ComponentScan中定义一个包名 喜欢:

@SpringBootApplication
@ComponentScan({"com.project.pck_name"})
public class MainClassHome {

    public static void main(String[] args) {
        SpringApplication.run(MainClassHome.class, args);
    }
}

然后更新项目:- 右键单击您的项目 -> maven -> 更新项目

我们可以使用@Import 代替ComponentsScan。

@Configuration

@Import({PersonController.class})

public class MainClassHome {

    public static void main(String[] args) {
        SpringApplication.run(MainClassHome.class, args);
    }
}

假设主要方法在名为 com.setech.app 的包中,控制器在名为 com.setech.controller 的包中。

对于 spring-boot 1.3.x 向上尝试添加 "scanBasePackages" 像这样。

@SpringBootApplication(scanBasePackages = { "com.setech"} )
public class ResttanslatorApplication {

    public static void main(String[] args) {

        SpringApplication.run(ResttanslatorApplication.class, args);
    }

}

Kamil Wozniak 来自 here

对于Maven Case:如果你把controller放在另一个不同的子模块中(与main class不同),你应该在pom.xml.

中添加依赖

将 Springbootapplication(application.java) 文件移动到另一个包解决了我的问题。将它与控制器和存储库分开。您可以使用任意数量的包并有多个 controllers.But 使用 @ComponenScan(basePackages={" "," "}) 并提及所有包。

另外,您可能会遇到这个问题Consider defining a bean of type..点击

我发现,如果您将控制器 类 放在单独的 jar 中,@Componentscan 找不到 @RestControllers。 但是,@SpringBootApplication(scanBasePackages =.. 这个技巧做得更好。 我使用了发布列车 springboot spring-cloud-starter-parent, Greenwich.SR4 这解析为 spring boot 2.1.10.Release 因此,在此版本中,@SpringBootApplication <> @Componentscan 在这方面的行为。