根据Spring Doc -
配置组件扫描指令以与@Configuration类一起使用。提供与Spring XML的
<context:component-scan>
元素并行的支持。
在我的spring web应用程序中,有多个标记为@Configuration
的文件,以便在spring容器中注册@component
bean -
问题1 - 我们是否可以在@ComponentScan
类或所有 {{1}的任何中使用@Configuration
类?
问题2 -
我也在春天见过doc
@Configuration
为什么在这里扫描配置类本身。
编辑:基本上我对@Configuration
@ComponentScan(basePackageClasses = { MyConfiguration.class })
public class MyConfiguration extends WebMvcConfigurerAdapter {
...
}
的理解是扫描并注册立体声类型bean(例如@ComponentScan
,@componant
,@Controller
等。),为什么我们是注册@Services
Bean。
答案 0 :(得分:7)
问题1 -
是的,您可以在 @ComponentScan
注册bean,该配置bean在spring容器中注册。您可以将bean注册到容器中通过以下任何一种方式 -
@Configuration
或中注册rootcontext
bean
dispatchersevletcontext
。@Configuration
在容器中。假设您正在使用MvcConfig
类扫描组件 -
@ComponentScan(basePackages = {"xxxx","yyyy","zzzz"})
@Configuration
public class MvcConfig {
....
}
要在容器中注册MvcConfig
,您必须这样做 -
无论
new AnnotationConfigWebApplicationContext().register(MvcConfig.class);
或
new AnnotationConfigWebApplicationContext().register(AnotherConfig.class);
@Configuration
@Import({MvcConfig.class})
public class AnotherConfig {
....
}
问题2 -
这里spring不仅注册了MyConfiguration.class
,还注册了MyConfiguration
定义的包中存在的所有组件类。
答案 1 :(得分:1)
问题1的解决方案:
是的,您可以在尽可能多的配置类中使用@Componentscan
。这完全取决于你。它只是将一些特定包的各种带注释的类注册为bean。因此,如果您只需使用一个@Componentscan
,即就所有注释的类组件扫描,因为您想要的所有必需bean已被激活并注册在DispatcherServlet容器中。
问题2的解决方案:
@Configuration
@ComponentScan(basePackageClasses = { MyConfiguration.class })
public class MyConfiguration extends WebMvcConfigurerAdapter {
...
}
您的问题:为什么在这里扫描配置类本身?
这个@ComponentScan(basePackageClasses = { MyConfiguration.class })
提到MyConfiguration.class为例。问题是这是什么意思?
有两种方法可以通过basepackage
属性或basepackageclasses
对组件进行打包。这两个是相同的,但使用basepackageclasses
有两个好处:
它既是类型安全的,也为将来的重构增加了IDE支持
这只是意味着,将来你可以重命名(通过重构)一些基本的背板,并且由于你已经重命名了基础包,如果使用了basepackageclasses
,你不需要在配置类中更改@ComponentScan属性。
现在回到你的第二个问题。为什么将MyConfiguration.class指定为basepackageclasses
的{{1}}属性的值?
首先,让我们知道这一点:
@Componentscan
属性采用表示某个标记类的字符串值。那个Marker课告诉我:嘿!注册该类所在的包中存在的所有类,包括此类
因此,在您的回答中,所有这些类都将进行组件扫描,这些类存在于MyConfiguration.class所在的包中。
配置类以及标记类,以便组件扫描其他类。这也意味着所有带注释的类都将被注册,这些类存在于MyConfiguration.class所在的包中,包括MyConfiguration.class,因为它使用@Configuration注释进行注释
{{{ 1}}属性也可以包含其他类,如basepackageclasses
益处:
因此,如果重命名包,则没有问题,因为您有标记类,这有助于弹出查找包。这些标记类可能包含也可能没有任何内容,因为它只是作为查找包的标记。
答案 2 :(得分:0)
来自文档:
<强> Q1:强>
@Configuration使用@Component进行元注释,因此@Configuration类是组件扫描的候选者(通常使用Spring XML的元素),因此也可以像任何常规@Component一样利用@Autowired / @Inject。
@Configuration类不仅可以使用组件扫描进行自举,还可以使用@ComponentScan 注释自行配置组件扫描:
@Configuration
@ComponentScan("com.acme.app.services")
public class AppConfig {
// various @Bean definitions ...
}
<强> Q2:强>
basePackageClasses
public abstract Class<?>[] basePackageClasses
basePackages()的类型安全替代方法,用于指定要扫描带注释组件的包。 将扫描指定的每个类的包。
回答您编辑过的问题
在某些时候,您需要向Spring说明您的应用所需的bean。您可以使用例如:
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.scan("com.acme");
ctx.refresh();
MyService myService = ctx.getBean(MyService.class);
}
或使用旧的xml样式:
<context:component-scan base-package="com.acme" />
在@Configuration级别使用@ComponentScan,您将确保该配置类的所有依赖项都可用。将@CompenentScan与basePackageClasses一起使用,即可在类指定的同一个包中注册所有可用的组件。
如果您已经让Spring知道需要扫描哪些包,则可以在其他地方或方式进行扫描,您无需使用它。第二季度的代码只是春天能够做的一个例子。