提出问题:为什么通过启动类的 SpringApplication.run方法就可以启动一个项目?
@SpringBootApplication
@EnableDiscoveryClient //将微服务注册到注册中心
@ComponentScan("com.xyxy.gmall") //自定义包扫描,将自定义的bean注入到IOC容器中
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
String[] args 是运行方法时加载的一些启动参数:java -jar -Xms 512M -Xmx 512M
-Xms 堆内存的初始大小
-Xmx 堆内存的最大值
-Xmn 新生代大小
-Xss 每个线程的堆栈大小
…
查看我们引入的spring-boot-starter-web依赖会发现,它自带了一个tomcat依赖,启动时springBoot会自动帮我们把项目发布在tomcat中,所以启动日志里面有tomcat的一些信息,所以也就不需要像SSM框架一样手动部署tomcat
SpringBoot只是一个简化的工具,并不是新的技术,它的底层还是Spring------>IOC容器、AOP切面编程
SpringApplication.run(ProductApplication.class, args);
run方法的第一个作用就是初始化IOC容器
那么这个方法是怎么体现的Spring呢,这得点进看源码
Ctrl点入run方法查看,可以看到run是一个静态有返回值的方法,返回对象是ConfigurableApplicationContext
ConfigurableApplicationContext类又继承自ApplicationContext应用上下文
ApplicationContext应用上下文是什么,继续深入查看发现ApplicationContext继承了一堆的类,我们认识的就是BeanFactory,点进去看就会发现它们几个都继承了BeanFactory
BeanFactory是最底层的接口,这个就是IOC接口,BeanFactory就是存储bean对象的IOC容器
run方法传入了启动类的字节码文件ProductApplication.class
,也就是说,run方法初始化bean容器之后会去扫描启动类上的注解
@SpringBootApplication是一个复合注解,它里面除了包含声明接口相关的注解外,还有三个核心注解
简单来说就是当run方法启动创建了IOC容器之后,通过run方法传入的字节码文件ProductApplication.class IOC会扫描到启动类上的@SpringBootApplication注解,由启动类注解帮我们做三件事
逐个分析
标明是配置类,也就是说这个启动类有配置类的功能,定义的bean就会注入到IOC容器
启动类就可以这样写:
@SpringBootApplication
@EnableDiscoveryClient //将微服务注册到注册中心
@ComponentScan("com.atguigu.gmall") //自定义包扫描,将自定义的bean交由IOC容器管理
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
/**
* 类似于学习SSM框架里面的spring.xml的配置文件
*
*/
@Bean
public RedisTemplate redisTemplate() {
return new RedisTemplate();
}
}
包扫描注解,@SpringBootApplication里面的包扫描和我们自定义的包扫描注解不一样,自定义注解是我们可以指定扫描我们用的到的模块的工具包
而启动类注解自带的包扫描的注解会扫描启动类及其所在包的子包里面的所有类的注解-------@Service,@Mapper,@Controller等等
类似于学习SSM框架里面的spring.xml的配置文件:
涉及的是SpringBoot的两个核心原理:自动配置、起步依赖
顺着我们引入的父工程依赖就可以看到起步依赖帮助我们管理了很多jar包的版本
自动配置步骤:
①读取spring.factoris文件内容得到一个List
②利用java的反射机制可以通过类的全量路径名实例化对象
③如果实例化失败说明没有引入坐标,
④实例化成功,则初始化、注入IOC容器
自动配置原理说明:
@EnableAutoConfiguration注解里面有个@Import注解,加载了一个导入选择器
进入自动配置选择器AutoConfigurationImportSelector看看它是啥有啥用
通过选择器里面有个方法去加载元数据,也就是spring.factoris文件,这个文件里面有很多的类全限定路径
以redis的配置为例,找到全量路径名
根据全量路径会对类进行实例化
该类上面有个@EnableConfigurationProperties({RedisProperties.class})注解,通过这个注解会去扫描配置文件信息,这也就是为什么我们就只要引入redis坐标,在application.yml文件配置redis的信息就可以使用RedisTemplate类,因为自动配置会帮我们实例化
DataSource的加载也是同理