【问题标题】:Spring boot - beans configuration without @component annotationSpring boot - 没有@component注释的bean配置
【发布时间】:2021-07-21 16:42:15
【问题描述】:

作为我大学项目的一部分,我被要求实现一个简单的 spring-boot 应用程序(仅限后端),它可以通过 HTTP 请求与 Postman 通信。

该项目构建在控制器-服务-存储库架构中,仅包含 1 个实体(具有字符串内容的帖子对象)和 2 个端点(创建新帖子,获取所有帖子)。

我知道在 spring-boot 中配置 bean 有几种方法:

  1. 使用外部 XML 文件。
  2. 带有@Configuration注解和@Bean注解
  3. 带@Component注解(@RestController,@Service,@JpaRepository)

第三种方式效果很好,但我被要求实施第二种方式,我真的很难让它发挥作用。

我得到:

ServletException: 循环视图路径 [post]: 将再次分派回当前处理程序 URL [/post]。检查您的 ViewResolver 设置!

试图探索这个异常,我确实设法通过添加这个 maven 依赖来“解决”它:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
    <version>2.5.2</version>
</dependency>

导致:

"org.thymeleaf.exceptions.TemplateInputException: Error resolving template [post], template might not exist or might not be accessible by any of the configured Template Resolvers"

我做错了什么?

配置类:

@Configuration
@EnableJpaRepositories(basePackages = {
        "com.example.microblog.post.domain.repository"
})
public class ApplicationBeans {

    @Bean
    public PostController postController(PostService postService){
        return new PostController(postService);
    }

    @Bean
    public PostService postService(){
        return new PostService();

    }

}

控制器类:

@AllArgsConstructor
@RequestMapping(path = "post")
public class PostController {

    @Autowired
    private PostService service;

    @CrossOrigin(origins = "http://localhost:4200")
    @PostMapping("")
    public PostEntity create(@RequestBody PostDto dto) {
        return service.create(dto);
    }

    @GetMapping("/all")
    @CrossOrigin(origins = "http://localhost:4200")
    public List<PostEntity> getAll() {
        return service.getAll();
    }

}

服务类:

@Transactional
public class PostService {

    @Autowired
    private PostRepository PostRepository;


    public PostEntity create(PostDto dto){
        PostEntity newPost = new PostEntity(dto.getContent());
        return PostRepository.save(newPost);
    }

    public List<PostEntity> getAll(){
        return PostRepository.findAll();
    }

存储库类:

public interface PostRepository extends JpaRepository<PostEntity,Long> {}

【问题讨论】:

  • 请发布您的实际代码,而不是您的代码图像。更容易全面了解情况,而且帮助尝试帮助的人花费的时间也更少。
  • 请注意,还有另一个选项,这是我用于大部分 bean 的选项:您可以在 @Configuration 上使用 @Import(MyService.class)(包括您的 @SpringBootApplication,用于小型程序)。

标签: java spring spring-boot


【解决方案1】:

对于第二种方法,当你创建一个 Bean 时,尽量不要在你创建 bean 的类上使用 @Component/@Controller ...

@Configuration
public class AppConfig {
    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl();
    }
}

你可以像第三种方法一样继续自动装配它们,尽量不要保留同名的bean

【讨论】:

  • “当你创建一个 Bean 时,尽量不要有 @Component/@Controller”——这正是我被要求做的,也是我想要实现的,但是你可以看到我们的代码,我们的代码很漂亮类似,它不起作用。我怎样才能解决那个 TemplateInputException ?
【解决方案2】:

您的错误指向方向,即您的控制器难以将您的服务的答案解析为有效的 JSON 响应。

注意@RestController 只是添加@Controller 和@ResponseBody 注解的一种便捷方式。当您只添加@Bean 注释时,您不会添加@Controller 或@ResponseBody。 如果您想使用 Controller 类而不使用这些 Annotation,则需要实现这些类提供的功能。

但是我真的看不出来,为什么选项 2 会用于 Controller 类。如果您想将它用于@Service 类(与@Component 的作用相同),您可以使用 Ravi 建议的方法。

【讨论】:

    猜你喜欢
    • 2014-06-30
    • 1970-01-01
    • 2016-10-31
    • 2016-05-07
    • 2014-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多