Java Spring-如何正确使用@Autowired?

Java Spring-如何正确使用@Autowired?,java,spring,jpa,Java,Spring,Jpa,我在我的Spring应用程序中发现了一个奇怪的行为 实体的@autowired不总是工作 我使用该项目来构建JSONAPI和一些自定义控制器 在一个控制器中,实体的一个@Autowrited保持为null,但是当从Elide调用时,它可以正常工作 控制器: @RestController public class UploadController { @Autowired private ProjectRepository projectRepository; @Pos

我在我的Spring应用程序中发现了一个奇怪的行为

实体的@autowired不总是工作

我使用该项目来构建JSONAPI和一些自定义控制器

在一个控制器中,实体的一个@Autowrited保持为null,但是当从Elide调用时,它可以正常工作

控制器:

@RestController
public class UploadController {
    @Autowired
    private ProjectRepository projectRepository;

    @PostMapping(value = "/api/projects/{projectId}/upload")
    public String uploadItem(@PathVariable long projectId, @RequestParam("file") MultipartFile file,
                              @RequestParam("projectName") String projectName,
                              RedirectAttributes redirectAttributes) throws IOException {
        Project project = projectRepository.findOneByProjectIdAndName(projectId, projectName);
        Integer result = project.getNumberOfItems();

        return "";
    }
}
实体

@Setter
@NoArgsConstructor
@Table(name = "projects")
@Entity
@Include(rootLevel = true, type = "projects")
public class Project extends DiffShelfBase {

    @Autowired
    @Transient
    private ItemRepository itemRepository;

    @Transient
    @ComputedAttribute
    public Integer getNumberOfItems() {
        return itemRepository.countByProjectId(this.getId());
    }
}
存储库

@Repository
@Transactional
public interface ItemRepository extends JpaRepository<Item, Long> {
    Integer countByProjectId(long projectId);
}

我不明白为什么,但是Project.getNumberOfItems中的itemRepository为null。

您的问题是,您的项目不是由spring管理的。您必须将@Configurable注释添加到类中。然后,您的自动连线注释将工作


但我真的会重构你的代码。实体中不应该有spring对象。

问题是,您的项目不是由spring管理的。您必须将@Configurable注释添加到类中。然后,您的自动连线注释将工作


但我真的会重构你的代码。您的实体中不应该有spring对象。

这不是您应该如何做到这一点的方法。不要在实体中使用@Autowired。此注释由Spring管理,但您的实体由Hibernate管理和创建,它不关心Spring注释。例如,您可以找到另一种方法将此属性添加到数据库的entitylet it be字段中。

这不是您应该如何做的方法。不要在实体中使用@Autowired。此注释由Spring管理,但您的实体由Hibernate管理和创建,它不关心Spring注释。例如,您可以找到另一种方法将此属性添加到数据库中的entitylet it be字段。

一个实体应该是一个美化的POJO,不要在其中嵌入repos使其复杂化

因此,autowire ItemRepository可以升级到一个级别,即atUploadController本身

作为一个好的实践,您可以随时进行构造函数注入,使其易于测试

e、 g.代替

进行构造函数注入

这样,

通过传递mockito实例很容易进行测试。 你可以做 final,在变量上直接使用@Autowire是不可能的 一个实体应该是一个荣耀的POJO,不要将回购协议嵌入其中使其复杂化

因此,autowire ItemRepository可以升级到一个级别,即atUploadController本身

作为一个好的实践,您可以随时进行构造函数注入,使其易于测试

e、 g.代替

进行构造函数注入

这样,

通过传递mockito实例很容易进行测试。 你可以做 final,在变量上直接使用@Autowire是不可能的
出于好奇,处理大量可配置实例时对性能有什么影响?似乎它是基于AOP代理的。你对此有直接的经验吗?谢谢,但是@Configurable还不够。你知道Vlad的答案是否100%准确吗?我找到了另一个答案。检查:@Charles,您不是缺少EnableSpringConfigured配置注释吗?谢谢,但即使在MyConfiguration中添加@EnableSpringConfigured和在Project中添加@Configurable,它也不起作用。出于好奇,在处理大量可配置实例时,对性能有何影响?似乎它是基于AOP代理的。你对此有直接的经验吗?谢谢,但是@Configurable还不够。你知道Vlad的答案是否100%准确吗?我找到了另一个答案。检查:@Charles,你不是缺少EnableSpringConfigured配置注释吗?谢谢,但即使在MyConfiguration中添加@EnableSpringConfigured和在Project中添加@Configurable,它也不起作用。这很烦人!这是合理的逻辑…:这太烦人了!这是合理的逻辑…:谢谢你的回答。正如我所说,我正在使用Elide创建一个JSONAPI接口。Elide使用getNumberOfItems通过JSONAPI发送到我的JavaScript应用程序。这工作得很好,这就是为什么我想知道为什么它不能从控制器工作。我完全理解这是一个糟糕的做法,但我创造了一个MVP,我更喜欢快速和肮脏的atm代码…啊,好的。明白了,谢谢你的回答。正如我所说,我正在使用Elide创建一个JSONAPI接口。Elide使用getNumberOfItems通过JSONAPI发送到我的JavaScript应用程序。这工作得很好,这就是为什么我想知道为什么它不能从控制器工作。我完全理解这是一个糟糕的做法,但我创造了一个MVP,我更喜欢快速和肮脏的atm代码…啊,好的。知道了。
@Configuration
@EnableSpringConfigured
public class MyConfiguration {
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedMethods("*")
                        .allowedOrigins("http://localhost:4200");
            }
        };
    }
}
@RestController
public class UploadController {

    @Autowired
    private ProjectRepository projectRepo;

    @Autowired
    private ItemRepository itemRepo;

    @PostMapping(value = "/api/projects/{projectId}/upload")
    public String uploadItem(@PathVariable long projectId, @RequestParam("file") MultipartFile file,
                              @RequestParam("projectName") String projectName,
                              RedirectAttributes redirectAttributes) throws IOException {

        Project project = projectRepo.findOneByProjectIdAndName(projectId, projectName);
        Integer result = itemRepo.countByProjectId(project.getId());

        return "";
    }
}
@Autowired
private ProjectRepository projectRepo;

@Autowired
private ItemRepository itemRepo;
private final ProjectRepository projectRepo;
private final ItemRepository itemRepo;

@Autowired
public UploadController(final ProjectRepository projectRepo, final ItemRepository itemRepo) {
    this.projectRepo = projectRepo;
    this.itemRepo = itemRepo;
}