深入理解SpringBoot中的自动装配

SpringBoot的自动装配是拆箱即用的基础,也是微服务化的前提。
看源码
一、自动装配过程分析

1.1、关于@SpringBootApplication

我们在编写SpringBoot项目时,@SpringBootApplication是最常见的注解了,我们可以看一下源代码:

package org.springframework.boot.autoconfigure;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.annotation.AliasFor;

/**
 * Indicates a {@link Configuration configuration} class that declares one or more
 * {@link Bean @Bean} methods and also triggers {@link EnableAutoConfiguration
 * auto-configuration} and {@link ComponentScan component scanning}. This is a convenience
 * annotation that is equivalent to declaring {@code @Configuration},
 * {@code @EnableAutoConfiguration} and {@code @ComponentScan}.
 *
 * @author Phillip Webb
 * @author Stephane Nicoll
 * @since 1.2.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

    /**
     * Exclude specific auto-configuration classes such that they will never be applied.
     * @return the classes to exclude
     */
    @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "exclude")
    Class<?>[] exclude() default {};

    /**
     * Exclude specific auto-configuration class names such that they will never be
     * applied.
     * @return the class names to exclude
     * @since 1.3.0
     */
    @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName")
    String[] excludeName() default {};

    /**
     * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}
     * for a type-safe alternative to String-based package names.
     * @return base packages to scan
     * @since 1.3.0
     */
    @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    String[] scanBasePackages() default {};

    /**
     * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to
     * scan for annotated components. The package of each class specified will be scanned.
     * <p>
     * Consider creating a special no-op marker class or interface in each package that
     * serves no purpose other than being referenced by this attribute.
     * @return base packages to scan
     * @since 1.3.0
     */
    @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
    Class<?>[] scanBasePackageClasses() default {};

}

这里面包含了@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan;
此处@ComponentScan由于没有指定扫描包,因此它默认扫描的是与该类同级的类或者同级包下的所有类;

@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

这里解释一下@Filter注解,从官方的翻译上了解到,这就是一个:声明类型过滤器

//类型为默认的
type = FilterType.CUSTOM

//当然,从源码中可以看到有很多种
public enum FilterType {

	/**
	 * Filter candidates marked with a given annotation.
	 * 用给定注释标记的筛选候选
	 * @see org.springframework.core.type.filter.AnnotationTypeFilter
	 * 按照注解的方式进行扫描.后面classes属性,为注解的类型
	 */
	ANNOTATION,

	/**
	 * Filter candidates assignable to a given type.
	 * 可分配给给定类型的筛选候选对象。
	 * @see org.springframework.core.type.filter.AssignableTypeFilter
	 * 按照指定的类,进行过滤,后面的classes属性的值为"类名.class"
	 */
	ASSIGNABLE_TYPE,
	//以上两种方式为常用的过滤方式.
	/**
	 * Filter candidates matching a given AspectJ type pattern expression.
	 * 筛选匹配给定AspectJ类型模式表达式的候选对象。
	 * @see org.springframework.core.type.filter.AspectJTypeFilter
	 */
	ASPECTJ,

	/**
	 * Filter candidates matching a given regex pattern.
	 * 筛选匹配给定正则表达式模式的候选对象。
	 * @see org.springframework.core.type.filter.RegexPatternTypeFilter
	 * 按照自己自定义的方式来进行过滤和筛选
	 * (使用此过滤类型,虽然比较繁琐,但是使用起来完全可以由自己来定义扫描的规则)
	 */
	REGEX,

	/** Filter candidates using a given custom
	 * 使用给定的自定义筛选候选对象
	 * {@link org.springframework.core.type.filter.TypeFilter} implementation.
	 */
	CUSTOM

}

在后面的classes中可以看到SpringBoot用的是TypeExcludeFilter

classes = TypeExcludeFilter.class
/**
从官方的理解上来看,TypeExcludeFilter是一个
属性中加载的类型过滤器类型过滤器}
{@link BeanFactory}并自动应用到{@code SpringBootApplication}
扫描。也可以直接使用{@code @ComponentScan},如下所示:
< pre类=“代码”>
ComponentScan(excludeFilters = @Filter(type = FilterType);自定义,class = TypeExcludeFilter.class))
< / >之前
< p >
实现应该提供一个注册为{@link BeanFactory}和的子类
重写{@link #match(MetadataReader, MetadataReaderFactory)}方法。他们应该
还要实现一个有效的{@link #hashCode() hashCode}和{@link #equals(Object) equals}
方法,以便它们可以用作Spring test的应用程序上下文缓存的一部分。
< p >
注意,{@code TypeExcludeFilters}在应用程序的很早就初始化了
在生命周期中,它们通常不应该依赖于任何其他bean。他们是
主要用于内部支持{@code spring-boot-test}。
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值