--在使用spring-boot的时候踩过太多的坑,很多都是因为不懂spring真正的原理造成的,所以写下这么篇文章,希望这篇文章能够帮助大家理解spring真正原理少走弯路

一:启动原理

--每个程序都有一个主入口,也就是main方法,main里面调用SpringApplication.run()启动整个spring-boot程序
eg:一个最简单的spring-boot启动类
@SpringBootApplication
public class Springrun{public static void main(String[] args) {SpringApplication.run(Springrun.class, args);}
}

解释:
--@SpringBootApplication继承了@Configuration、@EnableAutoConfiguration、@ComponentScan,这三个注解的特性后面会讲到,默认扫描的包是以SpringApplication.run(Springrun.class, args) 参数springrun.class所在的包作为base package。
注意:如果想要启动整个程序,这个类必须要放到根包里面去。

run方法执行顺序:
1.初始化SpringApplicationRunListeners并且开始监听
2.加载StandardEnvironment(包括系统参数   环境变量参数 properties/yml文件   profiles)
3.把environment set到Listeners里面
4.默认通过AnnotationConfigApplicationContext扫描所有的注解类,创建并且注册bean(默认都是创建的单列)
5.创建context,并且把environment set到context里面
备注:如果需要初始化spring-boot即将完成的时候马上去做一些事情,我们可以实现CommandLineRunner该接口
分析:
SpringApplication在初始化的时候,会去创建environment,这里默认是创建的StandardEnvironment,接着这个类会去加载sources,其uml图如下
接着会创建spring的启动模式,spring的启动模式有很多:xml配置启动、annotation启动、文件启动、web启动等等如下
spring-boot默认是选择AnnotationConfigApplicationContext启动上下文,其类图如下
这个类直接间接实现了很多接口,包括beanFactory、resourceresolver、evenPublisher等等,集成所有spring需要的东西。
接着会去调用其父类AbstactApplicationContext.refresh()创建bean,这个方法只能调用一次。该方法执行的内容如下
其方法里面所使用的beanFactory是DefaultListableBeanFactory,次类的类图如下:
这个类解决的问题是创建bean,包括一些简单的bean,还有一些有依赖的bean。
注意:
在运行main经常程序会退出,抛出Process finished with exit code 0,原因是程序运行main方法结束退出,出现这样的原因是maven导入jar出错没有导入依赖的容器(jetty or tomcat),最简单的跑起main方法并且不停止,只需要在maven引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.3.3.RELEASE</version>
</dependency>

二:配置属性加载

spring-boot 属性分为两种:
1.spring-boot默认属性(application.properties或者application.yml  系统属性  环境变量属性)
2.自定义加载属性

spring-boot启动的时候会默认扫描resources目录下面的application.properties或者application.yml,扫瞄结束后会把值放入到Environment。
初始化bean的时候需要用到配置的值,我们可以根据这三种方式去获取:
1).继承EnvironmentAware获取Environment
2).通过注解@value进行填充值
3).注入environment  通过environment获取
具体代码:

@Configuration
public class MyProperty  implements EnvironmentAware {public void setEnvironment(Environment environment) {//方案一   继承EnvironmentAware    获取yml里面的值RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(environment, "jdbc.");String url = propertyResolver.getProperty("url");}//方案二  通过注解value进行填充值@Value("${jdbc.url}")private String url;//方案三  注入environment  通过environment获取@Autowiredprivate Environment environment;public void init(){RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(environment, "jdbc.");String url = environment.getProperty("url");}
}

如果需要改造加载方式,比如先去远程或者数据库获取配置项,没有的话再读取本地的application.properties,
需要用到PropertyPlaceholderConfigurer这个类,此类所适用的@Value("${jdbc.url}")占位符,占位符先去PropertyPlaceholderConfigurer资源类找,
找不到的话再去Environment环境里面找

/**
*此类优先加载级别非常高,所以不需要担心其它需要用到属性值的类无法获取属性值
*/
@Configuration
public class ConfigConfiguration {@Beanpublic PropertyPlaceholderConfigurer initPropertyPlaceholder() {//创建占位符类PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();Properties[] properties = new Properties[3];//TODO add propertiesppc.setPropertiesArray(properties);return ppc;}
}

如果需要修改Environment里面的属性我们可以这么做:

/**
*spring 会自动注入applicationContext 到此方法参数
*/
@Bean
public String changeEnvironment(PropertiesCache propertiesCache, ApplicationContext applicationContext){//支持Environment获取  修改容器里面StandardServletEnvironmentStandardEnvironment standardEnvironment =applicationContext.getBean(StandardEnvironment.class);standardEnvironment.getPropertySources().addLast(new PropertiesPropertySource(null, null));return null;
}

三:annotation总结分析

基于类的注解:
--初始装载
@SpringBootApplication              spring-boot程序入口标志类
@Configuration                             自动配置,类似于加载spring加载xml 装配所有的bean事务等 所标识的类里面可以使用@Bean 并且启动的时候会初始化bean
@EnableAutoConfiguration       Spring-Boot 根据应用所声明的依赖来对Spring框架进行自动配置
@ComponentScan                     规定扫描包的范围
@PropertySources                  property扫描加载
--业务区分
@Component 定义该bean为一个普通组件
@Repository 定义该bean是一个仓储,用于数据库、mq、redis以及其它一些远程访问的资源
@Service  定义该bean是一个业务逻辑
@Controller  定义该bean是一个控制页面访问层
--加载条件
@Order  配置加载顺序
@ConditionalOnClass  该注解的参数对应的类必须存在,否则不解析该注解修饰的配置类;
@ConditionalOnMissingBean  该注解表示,如果存在它修饰的类的bean,则不需要再创建这个bean;可以给该注解传入参数例如@ConditionOnMissingBean(name = "example"),这个表示如果name为“example”的bean存在,这该注解修饰的代码块不执行。
@AutoConfigureAfter 在摸个自动装载类之后装载

基于属性的注解:
@Value 加载配置属性的值
@Autowired 自动注入bean
@Qualifier 当存在多个bean注入时,需要通过name进行过滤
@Resource 获取当前jvm的resource 也类似依赖注入
@Inject 字段注入bean

基于方法的注解:
@Bean  发布一个返回object类型的bean,类似配置xml发布一个bean
@PostConstruct 指定当类加载完成的时候就会执行该方法

四:mybatis集成

public class MybatisConfiguration {private static Log logger = LogFactory.getLog(MybatisConfiguration.class);//创建DataSource  @Beanpublic DataSource dataSource(Environment env) {DruidDataSource druidDataSource = new DruidDataSource();druidDataSource.setPassword(env.getProperty("jdbc.password"));druidDataSource.setUsername(env.getProperty("jdbc.username"));druidDataSource.setUrl(env.getProperty("jdbc.url"));druidDataSource.setDriverClassName(env.getProperty("jdbc.driver"));druidDataSource.setMaxActive(Integer.parseInt(env.getProperty("jdbc.poolMaximumActiveConnections")));return druidDataSource;}//创建SqlSessionFactory  DataSource spring会自动导入到参数@Beanpublic SqlSessionFactory sqlSessionFactory(DataSource dataSource) {try {SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();sessionFactory.setDataSource(dataSource);//set  map.xml的路径sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapping/*.xml"));return sessionFactory.getObject();} catch (Exception e) {logger.error("not install sessionFactory", e);throw new RuntimeException("not install sessionFactory");}}//创建事务  DataSource spring会自动导入到参数@Beanpublic DataSourceTransactionManager transaction(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}

结记:spring-boot是较好的微服务实现容器,减少开发调试时间,并且非常好的对微服务支持,而微服务又需要利用微服务框架实现,微服务框架可以查看本人另外一片文章详细说明基于grpc的服务化框架

spring-boot 深入学习相关推荐

  1. Spring Boot的学习之路(03):基础环境搭建,做好学习前的准备工作

    1. 前言 <论语·魏灵公>:"工欲善其事,必先利其器.居是邦也,事其大夫之贤者,友其士之仁者." 工欲善其事必先利其器.我们在熟悉一个陌生项目的时候,首先会大概去看一 ...

  2. spring boot框架学习学前掌握之重要注解(2)-通过java的配置方式进行配置spring

    本节主要内容: 1:通过代码演示实现零XML配置spring 2:使用重点注解理解 声明: 本文是<凯哥陪你学系列-框架学习之spring boot框架学习>中spring boot框架学 ...

  3. Spring Boot 2 学习笔记(2 / 2)

    Spring Boot 2 学习笔记(1 / 2) - - - 45.web实验-抽取公共页面 46.web实验-遍历数据与页面bug修改 47.视图解析-[源码分析]-视图解析器与视图 48.拦截器 ...

  4. Spring Boot的学习之路(02):和你一起阅读Spring Boot官网

    官网是我们学习的第一手资料,我们不能忽视它.却往往因为是英文版的,我们选择了逃避它,打开了又关闭. 我们平常开发学习中,很少去官网上看.也许学完以后,我们连官网长什么样子,都不是很清楚.所以,我们在开 ...

  5. spring boot框架学习2-spring boot核心(1)

    本节主要: 1:解析spring boot入口和@SpringBootApplication源码详解 SpringBootApplication包含: @SpringBootConfiguration ...

  6. Spring Boot 框架学习笔记(五)( SpringSecurity安全框架 )

    Spring Boot 框架学习笔记(五) SpringSecurity安全框架 概述 作用 开发示例: 1. 新建项目 2. 引入依赖 3. 编写`SecurityConfig`类,实现认证,授权, ...

  7. 10个Spring Boot 优秀学习项目

    10个Spring Boot 优秀学习项目 10个SpringBoot项目分享(好像多了一个项目) 一.mall (虽然培训机构已经把电商推广了烂大街了,但技术还是可以学习的) 二.Cloud-Pla ...

  8. 开源的13个Spring Boot 优秀学习项目

    开源的13个Spring Boot 优秀学习项目!超53K星,一网打尽! 原创: 徐刘根 Java后端技术 5月19日 Spring Boot 算是目前 Java 领域最火的技术栈了,也是Java开发 ...

  9. Spring Boot 框架学习笔记(二)(配置文件与数据注入 yaml基本语法 JSR303数据验证 多环境切换 )

    Spring Boot 框架学习笔记(二) 六.appliaction.properties配置与数据注入 6.1 `@Value`注解 测试注入数据 读取输入流 6.2 读取配置文件数据注入 单文件 ...

  10. Spring Boot配置文件学习记录【1】

    [1]Spring Boot配置文件 Spring Boot配置层面的知识已学习完.总结一下本周的学习内容,一切都需要从@SpringBootApplication谈起,因为它,做到了真正配置文件的简 ...

最新文章

  1. [JavaScript] JavaScript 值类型使用:与数组有关的API
  2. Solidity基础入门知识(十)函数的访问权限和可见性
  3. 北京、广州同时开课 | 临床基因组学数据分析实战助力解析Case,快速发表文章...
  4. 程序内存区域分配(五个段)--终于搞明白了
  5. python面向对象编程的优点-Python入门之面向对象编程(一)面向对象概念及优点
  6. 【OpenGL】十四、OpenGL 绘制三角形 ( 绘制 GL_TRIANGLE_STRIP 三角形 | GL_TRIANGLE_STRIP 三角形绘制分析 )
  7. postman+newman+jenkins环境部署
  8. 北斗导航 | 学习PPP和PPP-RTK
  9. 窗体之间传值的暴力方法
  10. CodeForces - 1465E Poman Numbers(推公式+贪心)
  11. 期待已久的Java 9 今日发布
  12. html 将两个标签绑在一起,基本标签2
  13. android 抓包 2
  14. 腾讯云轻量服务器和虚拟主机有什么区别?
  15. 视频字幕文件 SSA、ASS 参数-攻略
  16. LightGBM 原理、代码最全解读!
  17. 艾宾浩斯遗忘曲线PHP,艾宾浩斯遗忘曲线
  18. 简单网页制作代码 HTML+CSS+JavaScript香港美食(8页)
  19. 支付宝支付沙箱环境配置
  20. 【uniapp】【QA】

热门文章

  1. 公开「处刑」!波士顿动力的搬砖机器人,私下竟「翻车」不断
  2. dwm.exe(桌面窗口管理器)占用内存过大解决办法
  3. QWERTY键盘排列的历史
  4. CImage类之GetBits、GetPixel、GetPitch、GetBPP应用
  5. ffmpeg mp3转pcm指令
  6. R软件-ggplot2 画火山图
  7. arcgis for Android 100.3.0 加载shp数据以及操作
  8. 跟小静读CLR via C#-开篇及目录
  9. e与phi不互素 --- 五道题详记
  10. 根据SNP的位置从基因组提取上下游序列