SpringBoot--002--理解spring boot项目的自动装配

@SpringBootApplication
一、注解派生
  • 根据官方文档,该注解用于激活,@EnableAutoConfiguration、@Configuration、@ComponentScan
    • @ComponentScan:用于激活@Component的扫描,此注解属于spring framework
    • @Configuration声明被标注为配置类
    • @EnableAutoConfiguration:开启Spring boot自动装配机制。
  • 针对@ComponentScan,使用了excludeFilters过滤掉了两种不同情况的类
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
  • TypeExcludeFilter:用于查找BeanFactory中已经注册的TypeExcludeFilter Bean作为代理执行对象
@Override
//metadataReader spring中的类元信息
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
		throws IOException {
	if (this.beanFactory instanceof ListableBeanFactory && getClass() == TypeExcludeFilter.class) {
		//如果没有代理,就将此TypeExcludeFilterbean加入到spring中
		for (TypeExcludeFilter delegate : getDelegates()) {
			if (delegate.match(metadataReader, metadataReaderFactory)) {
				return true;
			}
		}
	}
	return false;
}

//获取代理
private Collection<TypeExcludeFilter> getDelegates() {
	Collection<TypeExcludeFilter> delegates = this.delegates;
	if (delegates == null) {
		delegates = ((ListableBeanFactory) this.beanFactory).getBeansOfType(TypeExcludeFilter.class).values();
		this.delegates = delegates;
	}
	return delegates;
}
  • AutoConfigurationExcludeFilter:用于排除其他同时标记@Configuration和@EnableAutoConfiguration的类
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
		throws IOException {
	//如果标注了configuration标签和EnableAutoConfiguration标签就排除
	return isConfiguration(metadataReader) && isAutoConfiguration(metadataReader);
}

private boolean isConfiguration(MetadataReader metadataReader) {
	return metadataReader.getAnnotationMetadata().isAnnotated(Configuration.class.getName());
}
注解派生
  • @ComponentScan仅仅关注@Component,然而由于@SpringBootConfiguration属于多层次的@Component派生注解,能够被ComponentScan识别。派生关系如下。
@Component
	@Configuration
		@SpringBootConfiguration
二、属性别名
  • 作用,使用属性别名,可以在注解中,对其他注解的属性进行设置,桥接其他注解的属性,通过配置exclude属性的值,就可以设置EnableAutoConfiguration中该属性的值,进而实现,不对某些类进行自动加载
  • 源码
@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) })
@ConfigurationPropertiesScan
public @interface SpringBootApplication {

	
	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class<?>[] exclude() default {};

	@AliasFor(annotation = EnableAutoConfiguration.class)
	String[] excludeName() default {};

	
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
	String[] scanBasePackages() default {};

	
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
	Class<?>[] scanBasePackageClasses() default {};

	
	@AliasFor(annotation = Configuration.class)
	boolean proxyBeanMethods() default true;

}
  • 验证:最终导致的结果是访问controller方法访问不到在这里插入图片描述在这里插入图片描述
三、标注非引导类
  • 引导类:指的是启动的类,带有main方法的类
  • 可以将@SpringBootApplication注解放到非引导类中,在引导类中的run方法中指明带有@SpringBootApplication的类即可。在这里插入图片描述
四、@SpringBootApplication“继承”@Configuration CGLIB提升
  • 在@Configuration注解的类,生成的bean对象属于“完全模式”,会执行CGLIB提升的操作。 而对于使用@Bean标签标注的bean对象,不会进行提升,称为“轻量模式”
  • CGLIB提升并非是为@Bean对象提供的,而是为@Configuration类准备的。
  • 演示:
    • 使用非@Configuration及派生注解,没有进行CGLIB提升在这里插入图片描述
    • 使用@Configuration或者派生注解,很显然得到了增强在这里插入图片描述
理解自动装配机制
  • 自动装配能够打包到外部的JAR文件中,并且被Spring boot装配。同时,自动装配也能被关联的starter中,这些starter提供自动装配的代码及关联的依赖。
  • spring boot中,提供了大量的内建自动装配@Configuration,统一存放在org.springframework.boot.autoconfigurate包或子包下,同时这些类均配置在META-INF/spring.factories资源中。所以如果导入自己的自动装配类,需要在启动方法加上@EnableAutoConfiguration,同时在META-INF/spring.factories资源中,加上org.springframework.boot.autoconfigure.EnableAutoConfiguration=加上了@Configuration的类,即可实现自动装配,导入。
  • 过程
    • 识别META-INF目录中的配置
      • 找到相关的配置类
        • 导入相关的类,进行加载,启动spring容器,启动项目
  • 示例
  1. 总体结构
    在这里插入图片描述
  2. spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.book.firstspringboot.config.WebAutoConfiguration
  1. WebAutoConfiguration
@Configuration
@Import(WebConfig.class)
public class WebAutoConfiguration {
}

  1. WebConfig
@Configuration
public class WebConfig {

    @Bean
    public FirstController firstController(){
        return new FirstController();
    }

    @Bean
    public ApplicationRunner runner(BeanFactory beanFactory){
        return args->{
            System.out.println("当前FirstController bean实现类为:"+
                    beanFactory.getBean("firstController").getClass().getName());
            System.out.println("当前WebConfig bean实现类为:"+
                    beanFactory.getBean(WebConfig.class).getClass().getName());

        };
    }
}

  1. 启动类
@EnableAutoConfiguration
public class FirstSpringbootApplication {

    public static void main(String[] args) {
        SpringApplication.run(FirstSpringbootApplication.class, args);
    }

}

总体流程
启动类通过@EnableAutoConfiguration开启自动装配
	->spring 自动装配扫描,spring.factories,找到WebAutoConfiguration
		-> 通过Import注解注入,真正的配置类,WebConfig
			->通过bean标签,注入Controller对象,启动项目

注意,在配置类上,不加入@Configuration也可以将内部的bean对象进行注入,但是配置类为原来的配置类即没有进行CGLIB增强,具体原因,后续注意。

  • 没有加@Configuration注解
    在这里插入图片描述
  • 加了@Configuration注解
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值