component-scan 和 annotation-config 配置

一、前沿

使用 SpringMVC 时,相信大家一定使用过 <context:component-scan/>  和 <context:annotation-config/> 这两个配置,它们的作用到底是什么呢?它们之前的区别在哪?下面分别为大家分析一下

二、作用

<context:annotation-config/> :用于激活哪些已经在 Spring 容器里注册过的 bean(无论是通过 xml 方式还是通过 package scan(包扫描)的方式的注解),没有在Spring容器中注册过的 bean ,它并不能执行任何操作

<context:component-scan/>:除了兼具 <context:annotation-config/> 功能外,还可以扫描指定包(package)下的 bean 以及注册 java bean

三、用法

下面通过demo示例给大家展示一下二者的用法,通过用法可以得知二者的区别之处

3.1 <context:annotation-config/>

xsd文件中定义如下:

	<xsd:element name="annotation-config">
		<xsd:annotation>
			<xsd:documentation><![CDATA[
	Activates various annotations to be detected in bean classes: Spring's @Required and
	@Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available),
	JAX-WS's @WebServiceRef (if available), EJB 3's @EJB (if available), and JPA's
	@PersistenceContext and @PersistenceUnit (if available). Alternatively, you may
	choose to activate the individual BeanPostProcessors for those annotations.

	Note: This tag does not activate processing of Spring's @Transactional or EJB 3's
	@TransactionAttribute annotation. Consider the use of the <tx:annotation-driven>
	tag for that purpose.

	See javadoc for org.springframework.context.annotation.AnnotationConfigApplicationContext
	for information on code-based alternatives to bootstrapping annotation-driven support.
			]]></xsd:documentation>
		</xsd:annotation>
	</xsd:element>

<context:annotation-config/> 配置中没有定义任何属性

实体类如下:

配置文件中 bean 的定义,配置文件中此时没有配置 <context:annotation-config/>

运行项目,输出结果:

从输出结果我们看到,虽然 setBbb 和 setCcc 方法上加了 Autowired 注解,但是 A 类中并没有依赖注入 B类 和 C类,原因是 Autowired 注解本身并不能够做任何事情,它们只是最基本的组成部分,我们需要能够处理这些注解的工具来达到注入的目的,这就是 <context:annotation-config/> 所做的事情,用于激活哪些已经在 Spring 容器里注册过的 bean

下面我们在配置文件中增加  <context:annotation-config/> 配置,然后在运行查看结果,如下:

此次运行结果表明,在 Spring 容器里注册过的 bean已经被激活了并依赖注入到了 A类中

3.2  <context:component-scan/> 

xsd文件中定义如下:

	<xsd:element name="component-scan">
		<xsd:annotation>
			<xsd:documentation><![CDATA[
	Scans the classpath for annotated components that will be auto-registered as
	Spring beans. By default, the Spring-provided @Component, @Repository, @Service,
	@Controller, @RestController, @ControllerAdvice, and @Configuration stereotypes
	will be detected.

	Note: This tag implies the effects of the 'annotation-config' tag, activating @Required,
	@Autowired, @PostConstruct, @PreDestroy, @Resource, @PersistenceContext and @PersistenceUnit
	annotations in the component classes, which is usually desired for autodetected components
	(without external configuration). Turn off the 'annotation-config' attribute to deactivate
	this default behavior, for example in order to use custom BeanPostProcessor definitions
	for handling those annotations.

	Note: You may use placeholders in package paths, but only resolved against system
	properties (analogous to resource paths). A component scan results in new bean definitions
	being registered; Spring's PropertySourcesPlaceholderConfigurer will apply to those bean
	definitions just like to regular bean definitions, but it won't apply to the component
	scan settings themselves.

	See javadoc for org.springframework.context.annotation.ComponentScan for information
	on code-based alternatives to bootstrapping component-scanning.
			]]></xsd:documentation>
		</xsd:annotation>
		<xsd:complexType>
			<xsd:sequence>
				<xsd:element name="include-filter" type="filterType"
					minOccurs="0" maxOccurs="unbounded">
					<xsd:annotation>
						<xsd:documentation><![CDATA[
	Controls which eligible types to include for component scanning.
	Note that these filters will be applied in addition to the default filters, if specified.
	Any type under the specified base packages which matches a given filter will be included,
	even if it does not match the default filters (i.e. is not annotated with @Component).
							]]></xsd:documentation>
					</xsd:annotation>
				</xsd:element>
				<xsd:element name="exclude-filter" type="filterType"
					minOccurs="0" maxOccurs="unbounded">
					<xsd:annotation>
						<xsd:documentation><![CDATA[
	Controls which eligible types to exclude for component scanning.
						]]></xsd:documentation>
					</xsd:annotation>
				</xsd:element>
			</xsd:sequence>
			<xsd:attribute name="base-package" type="xsd:string"
				use="required">
				<xsd:annotation>
					<xsd:documentation><![CDATA[
	The comma/semicolon/space/tab/linefeed-separated list of packages to scan for annotated components.
					]]></xsd:documentation>
				</xsd:annotation>
			</xsd:attribute>
			<xsd:attribute name="resource-pattern" type="xsd:string">
				<xsd:annotation>
					<xsd:documentation><![CDATA[
	Controls the class files eligible for component detection. Defaults to "**/*.class", the recommended value.
	Consider use of the include-filter and exclude-filter elements for a more fine-grained approach.
					]]></xsd:documentation>
				</xsd:annotation>
			</xsd:attribute>
			<xsd:attribute name="use-default-filters" type="xsd:boolean"
				default="true">
				<xsd:annotation>
					<xsd:documentation><![CDATA[
	Indicates whether automatic detection of classes annotated with @Component, @Repository, @Service,
	or @Controller should be enabled. Default is "true".
					]]></xsd:documentation>
				</xsd:annotation>
			</xsd:attribute>
			<xsd:attribute name="annotation-config" type="xsd:boolean"
				default="true">
				<xsd:annotation>
					<xsd:documentation><![CDATA[
	Indicates whether the implicit annotation post-processors should be enabled. Default is "true".
					]]></xsd:documentation>
				</xsd:annotation>
			</xsd:attribute>
			<xsd:attribute name="name-generator" type="xsd:string">
				<xsd:annotation>
					<xsd:documentation><![CDATA[
	The fully-qualified class name of the BeanNameGenerator to be used for naming detected components.
					]]></xsd:documentation>
					<xsd:appinfo>
						<tool:annotation>
							<tool:expected-type type="java.lang.Class"/>
							<tool:assignable-to type="org.springframework.beans.factory.support.BeanNameGenerator"/>
						</tool:annotation>
					</xsd:appinfo>
				</xsd:annotation>
			</xsd:attribute>
			<xsd:attribute name="scope-resolver" type="xsd:string">
				<xsd:annotation>
					<xsd:documentation><![CDATA[
	The fully-qualified class name of the ScopeMetadataResolver to be used for resolving the scope of
	detected components.
					]]></xsd:documentation>
					<xsd:appinfo>
						<tool:annotation>
							<tool:expected-type type="java.lang.Class"/>
							<tool:assignable-to type="org.springframework.context.annotation.ScopeMetadataResolver"/>
						</tool:annotation>
					</xsd:appinfo>
				</xsd:annotation>
			</xsd:attribute>
			<xsd:attribute name="scoped-proxy">
				<xsd:annotation>
					<xsd:documentation><![CDATA[
	Indicates whether proxies should be generated for detected components, which may be necessary
	when using scopes in a proxy-style fashion. Default is to generate no such proxies.
					]]></xsd:documentation>
				</xsd:annotation>
				<xsd:simpleType>
					<xsd:restriction base="xsd:string">
						<xsd:enumeration value="no"/>
						<xsd:enumeration value="interfaces"/>
						<xsd:enumeration value="targetClass"/>
					</xsd:restriction>
				</xsd:simpleType>
			</xsd:attribute>
		</xsd:complexType>
	</xsd:element>

<component-scan> 配置中定义了 base-package(required 必填)、annotation-config、name-generator、resource-pattern、scope-resolver、scoped-proxy 和 use-default-filters 七个属性

实体类定义:

我们先单独使用 <annotaion-config> 配置,运行结果如下:

没有任何输出结果,原因是 <context:annotation-config/> 仅能够使已经在Spring 中注册过的 bean 被激活,而此时没有任何bean通过任何方式注册到 Spring 容器中

要想使 bean 都被 Spring 容器管理到,这里只需要简单修改一下配置文件即可,运行结果如下:

此次运行结果完美的输出了我们想要的答案

结论:

<context:component-scan/> 除了具有 <context:annotation-config/> 功能外,还具有自动扫描指定包下的类,自动将带有 @Component、@Service、@Repository、@Controller 等注解的对象注册到 Spring 容器中

3.3  <context:annotation-config/> 和 <context:component-scan/> 同时配置

示例如下图:

结论:

 <context:annotation-config/> 和 <context:component-scan/> 同时配置的话<context:annotation-config/> 配置将会被忽略,也就是说那些 Autowired 和 Resource 注解只会被注入一次,哪怕是你手动地注册了多个处理器,Spring 仍然只会处理一次,这个在后面的 Spring 源码中会讲解,这里就不在做过多的赘述了

猜你喜欢

转载自blog.csdn.net/ywlmsm1224811/article/details/103201272