首先要明白这个概念,需要你在java基础对自定义注解和让注解生效有一定的理解
作为一个完整的springboot开发的web程序,这个注解是必不可少的;1.x的版本和这个有区别,大家参照文档去复制。
这个注解的作用是说明此类事SpringBoot的主配置类,SpringBoot应该运行这个类的main方法来启动SpringBoot应用
package com.qs; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }按住control查看这个注解的源码,回顾一下注解的基础 @Target:表示这个注解用在什么地方,比如类上、属性上、方法上、参数上等 @Retention:表示这个注解在什么时候有效,一般都是RetentionPolicy.RUNTIME @Documented:表示可以生成文档,回忆一下JAVA_HOME/bin/目录下的javadoc命令 @Inherited:表示是类有父子关系时,注解的作用域 @SpringBootConfiguration:spring的配置文件就是被这货给取代了,点击再看看就会发现这个注解上还有一个注解叫@Configuration,发现它上面有一个@Component,卧槽,是不是认识; @EnableAutoConfiguration:大家发现没有,我们写的控制器根本都没有配置到xml中,写好放那里就完事儿了,为什么它能直接被我们访问??这就是它的功劳 @ConponentScan:这个就是之前在applicationContext.xml配置的扫描标签,回忆一下是不是叫<context:component-scan base-package=“包路径”/>
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // 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.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.ComponentScan.Filter; import org.springframework.core.annotation.AliasFor; @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 { @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; }这个注解很重要,他是springboot中的注解,它也是一个组合注解(它脑壳上还有其他注解的),其中有一个叫做AutoConfigurationPackage
初学者因为它可能出现404问题,主要是类的放置问题
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // 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.context.annotation.Import; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; } 类乱放的同学们可以看这里,404是因为这里引起的。 如果你精通spring对象工厂创建对象的工程,看到这个静态类中的registerBeanDefinitions应该是秒懂;这个方法的主要目的是确定程序入口类所在的包,这个确定之后,只要是这个包下的类和子包的类都会被扫描到。否则spring的bean工厂是不会给你创建对象的,如果是控制器没扫描到,必须是404这个注解也给我们带来很多的方便,以后使用spring整合其它的框架的时候有些对象springboot就会自动帮助我们配置完成
点击去这个类并打上断点,debug模式启动web程序;发现有一大堆AutoConfiguration结尾的类。 请看上图截图代码的行号,找到79行,这里就是这些自动配置类的来源,点击进入getCandidateConfigurations方法 根据上图的断言提示应该能看出来,它其实是在找META-INF/spring.factories文件,继续点击loadFactoryNames方法往下跟 上图loadFactoryNames方法其实是调用的上图第二个方法loadSpringFactories方法实现的,大家看绿色的字体,正式这个文件。
看到没,只要是jar包后面带autoconfigure的包都包含META-INF/spring.factories
记得我们之前学习springmvc的时候,还需要自己在xml中配置springmvc的三大组件,但是我们写的springboot helloworld程序貌似并没有,原来是不是这样子写的,为什么不用配置了?
找到spring-boot-autoconfigure-2.2.2.RELEASE.jar,找到META-INFO/spring.factories,打开它,搜索webmvc会看到WebMvcAutoConfiguration类,control点进去 代码有点多,找不到请根据关键字搜索; 我们发现有一段如下代码;一个方法返回了一个InternalResourceViewResolver,这么巧,这不是我们之前配置的视图解析器吗?这个类上还有一个@Bean注解,之前不是这么写的吗?为啥都叫bean?我要告诉你的是这不是巧合,这是有预谋的。人家只是从xml搬家了,搬到类中了,类上的@Bean只要写在类上,就表示这个类的返回值交给spring容器来创建,和在xml中写是一回事。
以上讲的就是自动配置的道理
