我有一个多模块项目,但是我的配置有问题。 我在包nl.example.hots.boot
中有一个主要方法@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan(basePackages = {"nl.*"})
@EntityScan("nl.*")
public class HotsApplication {
public static void main(String[] args) {
SpringApplication.run(HotsApplication.class, args);
}
在nl.example.hots.core。*包中,我有以下课程:
@Service
@AllArgsConstructor
@Transactional(propagation = Propagation.REQUIRED)
public class MapImportService {
private MapInputModelMapper mapInputModelMapper;
private MapEntityRepository mapEntityRepository;
public void add(final MapInputModel mapInputModel) {
System.out.println(mapInputModel.getName());
mapEntityRepository.save(mapInputModelMapper.mapToEntiy(mapInputModel));
}
和:
@Component
@Mapper
public interface MapInputModelMapper {
MapInputModel mapToInputModel(final MapEntity n);
MapEntity mapToEntiy(final MapInputModel n);
}
存储库位于软件包nl.example.hots.persistence。*
中运行应用程序时出现以下错误:
Description:
Parameter 0 of constructor in nl.example.hots.core.dataimport.MapImportService.MapImportService required a bean of type 'nl.timonschultz.hots.core.map.mapper.MapInputModelMapper' that could not be found.
Action:
Consider defining a bean of type 'nl.example.hots.core.map.mapper.MapInputModelMapper' in your configuration.
当我删除@EnableAutoConfiguration和@ComponentScan批注时,它可以工作。该应用程序启动时没有bean错误。
在这种情况下,我的restcontroller不再起作用:
{
"timestamp": "2018-07-18T20:48:39.414+0000",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/maps"
}
当我删除MapImportService类(并且不会弹出Bean错误)时,它可以在相同的URL上工作。
package nl.example.hots.api.data_import;
@RestController
@AllArgsConstructor
public class ImportController {
private static final String URL = // a url
private Reader reader;
@RequestMapping("/maps")
public String abilityStreamImport() {
reader.readStream(URL); // calls a class in nl.example.hots.core.*
return "Greetings from APP!";
}
}
我尝试了几种不同的组合,并且我有一个不同的项目作为示例,其中注释一起使用,并且可以正常工作。有人可以解释为什么注释一起使用时会产生bean错误吗?为什么仅使用@SpringBootApplication时控制器会给出错误?
在我的Pom.XML中,启动模块对API层具有依赖性,对API层具有依赖性,而对核心层具有依赖性,而对核心层具有依赖性。 我在项目中使用了mapstruct和Lombok。
---编辑:资料库---
@Entity(name = "MAPS")
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class MapEntity extends HasId<Long> {
private String name;
@ElementCollection
private List<String> translations;
}
@Repository
public interface MapEntityRepository extends JpaRepository<MapEntity, Long> {
}
@MappedSuperclass
public abstract class HasId<T> {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Setter
@Getter
private T id;
}
项目结构:
hots-application;
- hots-api
- pom.xml
- nl.example.hots.api.dataimport.ImportController;
- hots-boot
- pom.xml
- nl.example.hots.boot.HotsApplication;
- hots-core
- pom.xml
- nl.example.hots.core.dataimport.mapImportService.MapImportService;
- nl.example.hots.core.map.mapper.MapInputModelMapper
- hots-persistence
- pom.xml
- nl.example.hots.persistence.common.HasId;
- nl.example.hots.persistence.map.MapEntity;
- nl.example.hots.persistence.map.MapEntityRepository;
pom.xml
答案 0 :(得分:4)
Spring Boot将扫描所有带@SpringBootApplication
注释类所在的软件包的软件包和子软件包。您的类位于nl.example.hots.boot
中,仅扫描该软件包。其他类别位于不同的非扫描软件包中。
由于采用了这种包结构,并且没有遵循best practices,因此您基本上失去了许多自动配置功能(Spring Data JPA,ReST等),而您不得不求助于手动启用/配置这些功能。对于JPA,部分地通过添加其他@ComponentScan
批注。但是,您还需要添加所有@EntityScan
等注释,因为这些注释不再被添加(至少没有使用正确的软件包)。
修复非常简单。将带注释的@EnableJpaRepository
类移动到@SpringBootApplication
包中(如best practices中所述)。除去nl.example.hots
以外的其他注释,只需启动您的应用程序。
答案 1 :(得分:1)
您在@AllArgsConstructor上缺少@Autowired注释,请尝试:
@AllArgsConstructor(onConstructor = @__(@Autowired))
答案 2 :(得分:0)
Spring没有创建MapInputModelMapperBean。我从未使用过MapStruct,但是这让我想起了mybatis。对我来说,您用@Mapper和@Component注释MapInputModelMapperBean似乎很奇怪。春天应该如何创造豆子?您是否正在使用执行这种魔术的某种spring-boot-mapstruct软件包?
我进行了快速搜索,发现了这个https://www.credera.com/blog/technology-solutions/mapping-domain-data-transfer-objects-in-spring-boot-with-mapstruct/,看来您需要这样的东西:
@Mapper(componentModel = "spring")
public interface MapInputModelMapper
我想这会生成带有@Component或类似内容的映射器的实现。
答案 3 :(得分:0)
经过反复试验,我设法使它在很大程度上发挥了作用。 我将scanBasePackages =“ nl”添加到SpringBootApplication批注中。
Mapstruct确实给我带来了一些麻烦,但是当我删除它并自己制作一个快速的映射器时,一切都很好。 感谢您提供的所有帮助,建议和链接,以继续阅读!在下一个项目中,我将牢记(最佳实践)建议。 下面是我现在的主要课程
package nl.example.hots.boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@SpringBootApplication(scanBasePackages = "nl")
@EntityScan("nl.*")
@EnableJpaRepositories("nl.*")
public class HotsApplication {
public static void main(String[] args) {
SpringApplication.run(HotsApplication.class, args);
}
}