我有两个Maven模块。第一个,叫做“应用程序”,包含了只包含以下行的弹性引导
Application类:
package org.example.application;
@SpringBootApplication
@ComponentScan({"org.example.model", "org.example"})
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
在同一个Maven模块和包org.example.application
中,我有一个RestController
,它使用Component
,然后使用下面描述的其他Maven模块的组件。
另一个名为“model”的Maven模块包含spring boot
组件(crud存储库、实体等)。所有这些类都与第一个Maven模块(org.example
)位于相同的包结构下,但都位于该模块的子包中,比如org。实例模型实体
,组织。实例模型存储库
等。
所以,流程是这样的:
Maven模块应用程序
包org.example:SpringBootApplication-
应该在
MyComponent
中自动连接的组件是包org下的
。model
Maven模块中的组件。实例型号
但当我启动应用程序时,我只得到一个错误:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field myRepository in org.example.MyComponent required a bean of type 'org.example.model.repositories.MyRepository' that could not be found.
Action:
Consider defining a bean of type 'org.example.model.repositories.MyRepository' in your configuration.
org。实例模型仓库。MyRepository
确实存在于Maven模块“model”中,但SpringBootApplication类找不到它!
如您所见,我试图将扫描组件显式定义为:
@ComponentScan({“org.example.model”、“org.example”})
,但这似乎没有帮助。
那么我做错了什么?
您应该想知道的第一件事是:为什么要声明@ComponentScan
,而@SpringBootApplication
的目标之一是启用组件扫描?
来自Spring Boot留档:
@SpringBootApplication
注释相当于使用@Configance
、@EnableAutoConfigance
和@ComponentScan
及其默认属性
请注意,在Spring Boot应用程序的类上,您声明@ComponentScan
以将值指定为basePackages
,它会覆盖@springboot应用程序
默认使用的basePackages
,后者是类所在的当前包。因此,要将Spring Boot应用程序类的包和缺少的其他包都作为基本包,必须显式地设置它们。
此外,basePackages
是递归的。因此,为了能够扫描位于“org.example”
和“org.example.model”
包中的类,指定“org.example”
就足够了,因为“org.example.model”
是它的一个子包。
试试看:
@SpringBootApplication(scanBasePackages={"org.example"})
或作为替代:
@SpringBootApplication
@ComponentScan("org.example")
在设计Spring Boot应用程序布局时,有两种情况:
1)使用包布局的情况,该布局提供了零配置的Spring Boot的自动配置。
总结一下:如果你的类用SpringBean原型注释:@Component
,@Repositories
,@Repositories
,。。。位于Spring Boot应用程序类的同一个包或子包中,只需声明@SpringBootApplication
即可。
2) (为了避免)不使用提供自动配置Spring Boot和零配置的包布局的情况。
这通常意味着您要扫描的候选类不在您的类的包(或子包)中,并用@SpringBootApplication
注释。
在这种情况下,您可以添加scanBasePackages
属性或添加@ComponentScan
来指定要扫描的包。
但是另外,如果您的存储库不位于您的类的包或子包中,并用@SpringBootApplication
注释,则必须声明其他东西,例如:@EnableJpaRepository(="PackageWhMyRepoArea")
以下是关于这一部分的文件(重点是我的):
80.3使用Spring数据存储库
Spring数据可以创建各种风格的@Repository接口的实现。只要这些@Repositories包含在@EnableAutoConfiguration类的同一个包(或子包)中,Spring Boot就可以为您处理所有这些。
对于许多应用程序,只需在类路径上放置正确的Spring数据依赖项(jpa有Spring boot starter Data jpa,mongodb有Spring boot starter Data mongodb),并创建一些存储库接口来处理@Entity对象。例如JPA示例和Mongodb示例。
Spring Boot试图根据它找到的@EnableAutoConfigance来猜测@Repository定义的位置。要获得更多的控制,请使用@EnableJpaRepository注释(来自Spring Data JPA)。
1)使用包布局的情况,该布局提供了零配置的Spring Boot的自动配置。
使用org中声明的Spring启动应用程序。示例
package,以及在同一个包或org的子包中声明的所有bean类(包括存储库)。示例
,以下声明对于Spring Boot应用程序已经足够了:
package org.example;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
存储库可以位于组织中。实例存储库
包,例如:
package org.example.repository;
@Repository
public interface FooRepository extends JpaRepository<Foo, Long>, { }
和
package org.example.repository;
@Repository
public interface BarRepository extends JpaRepository<Bar, Long>, { }
控制器可以位于组织中。实例控制器
软件包:
package org.example.controller;
@RestController
@RequestMapping("/api/foos")
public class FooController {...}
所以对于。。。
2) (为了避免)不使用提供自动配置Spring Boot和零配置的包布局的情况。
对于在org.example.application
包中声明的Spring Boot应用程序,并且并非所有bean类(包括存储库)都声明在同一包中或org.example.application
的子包中,Spring Boot应用程序需要以下声明:
package org.example.application;
@SpringBootApplication(scanBasePackages= {
"org.example",
"org.thirdparty.repository"})
@EnableJpaRepositories("org.thirdparty.repository")
public class Application {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
}
bean类可以如下所示。
可能来自外部JAR的存储库可以位于org中。第三方。存储库
包,例如:
package org.thirdparty.repository;
@Repository
public interface FooRepository extends JpaRepository<Foo, Long>, { }
和
package org.thirdparty.repository;
@Repository
public interface BarRepository extends JpaRepository<Bar, Long>, { }
控制器可以位于组织中。实例控制器
软件包:
package org.example.controller
@RestController
@RequestMapping("/api/foos")
public class FooController {...}
所以对于。。。
结论:建议在名称空间的基本包中定义Spring Boot应用程序,使Spring Boot配置尽可能简单。
我不明白的是包装是如何工作的。我现在脑子里全是意大利面。当Spring转到@componentscan行并看到“实体”和“服务”时,它看到的获取这些类的结构是什么? 我的包裹结构很简单。在服务模块中,我只有src/main/java/entities和src/main/java/services 这里的幕后发生了一些我不明白的事情。Spring怎么会聪明到知道这一点?我甚至不必列出完整的包,即my
我有1个应用程序和2个模块 框架结构 但我不能在MyApp中使用MyModule的文件。IDE显示我“无法访问”错误,我想扩展一个MyModule类的类。而且它不是从MyModule创建类的,有人对此有想法吗?怎么了?
我有一个遗留的Spring应用程序,不管上下文是否完全用XML配置。我想使用@controller注释向应用程序添加一个新的控制器,所以我开始迁移到使用注释。 作为测试,我在应用程序中添加了以下控制器 我还添加了上下文:组件扫描标记到我的Spring上下文 尽管classpath scanner(ClassPathScanningCandidateComponentProvider)选择了hell
我有一个Maven Java应用程序,我正在尝试进行对接。到目前为止,我有以下dockerfile,是我从这个答案中复制的。 如果我的应用程序是一个单模块项目,这将是很好的,但是因为它是多模块的,所以我假设我不能仅仅使用。 但是,这会在阶段出错: 注意,来自我的本地m2文件夹。
Player类如下所示: 前面的main方法(它使用多个扫描器,包括try-with-recours,没有任何错误或异常)如下所示:
Checkmarx扫描抱怨某些“元素的值在没有经过适当清理或验证的情况下流过代码,并最终在OnItemDataBound方法中显示给用户 或者 如何清理这些值?HTML编码和解码是否容易避免此类漏洞结果? 请注意,这是针对dot net应用程序的。