深入理解Spring(一)了解Spring运行的基础流程
作者:CSDN 双鱼座的老王
emoing.. 如果写的内容有误,或者错字之类的,请私信及时提醒谢谢!
目录
1.Spring的基本运行
2.关键词:BeanDefinition
3.关键词:BeanFactory
4.关键词:PostProcessor
5.关键词:BeanFactoryPostProcessor
6.关键词:Environment
Spring在一般情况下都分为两个部分
1.IOC :控制反转,由Spring进行创建对象,实现层解耦
2.AOP :面向切面变成,将工程代码与工具代码分离,实现主次解耦
这个东西谁都会说,没啥难的,只要听过Spring的课程,都会说,那么问题就在于,如果用Spring,那么他的对象是怎么创建的,怎么解耦的
那么由此可以延伸出几个问题,就是大家面试的时候常常见到的:
1.bean的生命周期2.FactoryBean和beanFactory3.ApplicationContext和BeanFactory的区别4.设计模式
我们聊到Spring,第一个听到的东西就是容器,例如IOC容器,对于当前的IOC容器而言,也是用来存在一些实际的事物(bean)那么bean中就引出来了一些数据结构的问题,所以啊,万物不离数据结构
我们先来大致了解一下Spring的机制:
从第一步看起,Spring是怎么做到IOC的创建对象呢?
1.Spring的基本运行
如图所示,在Container中,有许多许多的bean,我们可以通过context.getBean获取由Spring帮我们创建的对象。那么问题由此而来:
我们的bean是通过什么方式来创建的?
java中,常用的创建对象方式,要么就new,要么通过反射来创建,例如serve,Dao等类,都需要创建,于是乎,我们来看一下配置文件
<bean id=? class=?><property name=? value=?><property name=? ref=?></bean><bean id=? class=?><constructor-arg name=? value=?><constructor-arg name=? ref=?></bean>
所以,Spring中,大部分都是由反射来创建对象的,那么,我们就要对Spring中的大致流程有所了解
2.关键词:BeanDefinition
Spring就是一个婚姻介绍所中介,你向婚姻介绍所提交了一个申请。中介手里握着各种美女的联系方式,于是乎中介问你,你想要一个什么样的对象?要不然你给我说说你想要个啥样的?
于是乎你向中介提交了你的申请:
1.女的2.活得
于是乎,中介就随便给了你一个,但实际这个美女并不符合你的要求,你就有了一个新的需求
1.肤白 2.貌美 3.大长腿
然后中介就把迪丽热巴推给了你,完成了一次运行
那么,在这个例子中,男人就充当了用户(程序员)的角色,中介就是Spring的容器,那么美女从哪里来?如果容器中没有人,那么这个中介也不用开了。所以,如何让Spring给你想要的对象,就需要你提前定义好信息。就像上面配置文件(xml文件)中的bean。
那么,你所有的定义描述信息都在XML文件里面,如何读取呢?
new ClassPathXmlApplicationContext("applicationcontext.xml")
见过吗,这步在你的代码里就是读取XML文件,而Bean就在xml里面,于是乎,Bean的定义信息通过XML读取到了容器中,此时,IOC的容器出现了bean的定义信息,并赋予了一个名字:BeanDefinition
当然,这里仅仅是举例了xml文件,其他的定义文件也是可以的,就引出了下面的问题
例如数据库,那么多的数据库,JDBC是怎么全部都可以接受的呢?我们从JDBC中学习到了什么?
JDBC的解决方案,创建了一个接口,让各大数据库厂商重写接口,实现了通用化。那么Spring是怎么做到的呢?
答案是一样的,也是接口,定义了读取配置文件的规范。不论你是通过xml,yaml等等,你必须都要有一个子类实现此接口,规范了配置文件的问题。那么引出了一个关键词:BeanDefinitionReader,即为这个规范信息的接口。
3.关键词:BeanFactory
我们在使用Spring中,难道拿到bean的定义信息就完事了吗?那一定是不能使用的。Spring是怎么通过bean的定义信息,实例化了此对象。
对此,我们先要科普一下几个名词
1.实例化
2.初始化
这两个东西是特别容易混淆的,实例化是很直观的,即为在堆中开辟了一块空间,此时属性都为默认值。而初始化,即为给属性完成赋值。java中对这两步的区分不是很明显,所以很容易搞混
在初始化的时候,分为了两个操作
1.填充属性:赋值操作
2.调用具体的初始化方法
在我们的源码里面,这些东西都会有体现的,那么这些东西就必须弄清楚。
回到正题,实例化bean后,Spring执行初始化bean,然后你就获得了一个完整的bean对象
在当前的容器中,我们要完成一个关键的步骤(实例化),是怎么执行的?
我们知道,程序运行时的反射构建对象有三种方式
获取class对象Class clazz = Class.forName("完全限定名");Class clazz = 对象.getClass();Class clazz = 类.class;
如果你看过反射的方式,反射后续还会有操作
clazz.newInstance();
后来这种方式过时了,我们采用:
Constructor ctor = clazz.getDeclareConstructor();Object obj = ctor.newInstance();
那么Spring是不是用的反射呢?留着这个疑问,往下看,如果Spring中出现了这几行代码,那么Spring在实例化的时候用的即为反射机制。那么,由此我们引出了一个新的关键词BeanFactory工厂,工厂中存放了实例化方法。
4.关键词:PostProcessor
扩展:在面试的时候经常会被问一些接口,例如PostProcessor。(属实把我问懵了)
这个东西,可以理解为增强器(后置处理器),那么他的功能在Spring实现了什么?
答案是:扩展。
不论是后置处理器还是增强,最终完成的功能都是扩展,Spring虽然是个框架。但是Spring最重要的是一整个生态不论是SpringBoot 还是 SpringCloud 都是基于Spring,所以Spring必须有一个非常完好的扩展性。如果涉及到二次开发,那么一定会要用到PostProcessor。
举个例子:Druid ,在Spring中使用过Druid的朋友们绝对写过以下代码
<bean id=datasource class=com.alibaba.druid.poll.DruidDatasource><property name = username value=${jdbc.username}/>...</bean>
按照正常的Spring实例化逻辑,难不成我的username的值直接被初始化成了${jdbc.username}吗?答案一定是否定的,当我们对这个BeanDefinition通过BeanFactory实例化的时候,一定出现了一个什么东西把这个大括号中间的东西填充变成了一个对应的值。
那么我们就引出了一个新的关键词:BeanFactoryPostProcessor(BFPP)
5.关键词:BeanFactoryPostProcessor
他就会对我们定义的相关信息进行处理替换。俗话说数形结合百般好,上代码
/*** @program: Spring-01* @description: 实现BeanFactoryPostProcessor* @author: 老王* @create: 2022-01-09 09:28**/public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {//获取Key为aa的bean定义信息BeanDefinition aa = configurableListableBeanFactory.getBeanDefinition("aa");}}
在获取到aa的同时,我们可以通过aa.set看到
有兴趣的可以翻一下,反正,你可以通过这个接口进行对bean定义信息的编辑。通过个人实现这个接口,我们对于Spring的扩展性可以达到为所欲为。
6.关键词:BeanPostProcessor
我们到这里,了解到Spring是如何对bean操作的,接下来我们看看,容器对于实例化对象解锁了哪些新玩法。
我们引入一个新的关键词:BeanPostProcessor
这个在我们面试的时候经常会被问到,那么他在Spring中是干嘛的?
在BeanPostProcessor中有两个关键词
1:before
2:after
此时,我们应该引入Spring重要的部分 AOP 面向切面编程
对bean初始化方法之前,之后都有BeanPostProcessor的存在,我们可以通过个人实现BeanPostProcessor接口,从而来实现Spring的面向切面编程。
我们在IDEA中搜索BeanPostProcessor,打开实现类,会发现有一个实现类
打开这个实现类,找到protected Object createProxy方法,会发现方法最后return了proxyFactory的一个get方法,打开这个方法,我们得到了这个
public Object getProxy(@Nullable ClassLoader classLoader) {return this.createAopProxy().getProxy(classLoader);}
我们点getProxy进去会发现是一个AopProxy的接口,于是乎,我们查看一下该接口的实现类
眼熟吗,这就是AOP动态代理的两种方式,JDK以及Cgilb
由此我们可得知,BeanPostProcessor就是Spring实现AOP解耦的关键所在
我们此时回头看一下Spring的运行流程图,就会对Spring有一个大致的了解。
6.关键词:Environment
除了这些东西之外,Spring中还需要了解几个接口
Environment:他下面包含了两个部分
1.env
2.properties
大家在写Spring中一定写过这样的代码
public static void main(String[] args) {System.getenv();//获取环境System.getProperties(); //获取属性}
在整个Spring运行过程中,他会提前获取我们的环境与属性值,提前把我们的系统属性值加载到Environment中
我们尝试在IDEA中搜索Environment,可得知Environment下有一个特殊的实现类StandardEnvironment
该实现类下有一个customizePropertySources方法
protected void customizePropertySources(MutablePropertySources propertySources) {propertySources.addLast(new PropertiesPropertySource("systemProperties", this.getSystemProperties()));propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", this.getSystemEnvironment()));}
我们点击方法中的getSystemProperties以及getSystemEnvironment就可以得知
这两个方法确确实实加载了系统的环境和属性
所以,Environment接口存在的意义就是为了方便使用,在IOC容器创建的时候,提前加载系统的相关属性 加载到StandardEnvironment 方便后续使用
至此我们就讲完了,只能说是大致讲了一下spring创建IOC的过程以及如何实现AOP ,源码部分后续更新
深入理解Spring(一)了解Spring运行的基础流程相关推荐
- spring boot项目 中止运行 最常用的几种方法
spring boot项目 中止运行 最常用的几种方法: 1. 调用接口,停止应用上下文 @RestController public class ShutdownController impleme ...
- Spring MVC实现Spring Security,Spring Stomp websocket Jetty嵌入式运行
使用Spring框架各个组件实现一个在线聊天网页,当有用户连接WebSocket,服务器监听到用户连接会使用Stomp推送最新用户列表,有用户断开刷新在线列表,实时推送用户聊天信息.引入Jetty服务 ...
- spring boot编写并运行HelloWorld服务接口
spring boot编写并运行HelloWorld服务接口 在主程序上要加包扫描注解@ComponentScan("com.example.demo1") package com ...
- Spring容器和Spring应用上下文的理解
1. 什么是Spring容器?作用是什么? 1.1 什么是Spring容器? Spring容器称为IOC容器,即:控制反转 应用程序里不用再过问对象的创建和管理对象之间的依赖关系了,都让IOC容器给代 ...
- 使用pm2来保证Spring Boot应用稳定运行
使用pm2来保证Spring Boot应用稳定运行 原作者:dulingyulove 原文链接:https://www.bbsmax.com/A/KE5QmgZ35L/ Spring Boot开发w ...
- Spring Boot注解的运行原理
Spring Boot 是一个基于 Spring Framework 的开源框架,通过简化配置和开发过程,使 Spring 应用程序的开发变得更加快速和便捷.在 Spring Boot 中,注解是非常 ...
- Spring Security技术栈学习笔记(八)Spring Security的基本运行原理与个性化登录实现
正如你可能知道的两个应用程序的两个主要区域是"认证"和"授权"(或者访问控制).这两个主要区域是Spring Security的两个目标."认证&qu ...
- Spring系列之Spring常用注解总结
参看博客:https://www.cnblogs.com/xiaoxi/p/5935009.html 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺 ...
- spring学习12 -Spring 框架模块以及面试常见问题注解等
以下为spring常见面试问题: 1.Spring 框架中都用到了哪些设计模式? Spring框架中使用到了大量的设计模式,下面列举了比较有代表性的: 代理模式-在AOP和remoting中被用的比较 ...
最新文章
- java datetime int_关于jodatime:Java中DateTime对象之间的小数天数
- iPhoneX快速适配,简单到你想哭。
- Paypal IPN
- cnn卷积神经网络_卷积神经网络(CNN)原理及应用
- GitHub网站使用的基础入门
- 阿里巴巴Java开发手册中的DO、DTO、BO、AO、VO、POJO定义
- 高等数学下-赵立军-北京大学出版社-题解-练习8.5
- python语句print(type([1、2、3、4))_Python 学习第一天
- codeforces:ProblemMset
- jQuery-1.9.1源码分析系列(十一) DOM操作续——克隆节点
- Atitit 自然语言与人工语言的语法构建ast的异同点 目录 1. 语言节点gaishu。。 2 1.1. 节点、函数数量大约200个 2 1.2. 关键词节点 是 有 的 3 1.3. 标识符
- 校验和checksum、哈希值是什么?
- Mac之MySQL初始数据库密码问题
- 2021年「博客之星」参赛博主:smileNicky投票
- 计算机excel基础知识教程,EXCEL基本操作技巧 一
- javaScript:结合mousedown、mousemove、mouseup事件,实现拖动方块在页面内移动(代码)
- Java卸载删除(2023最强版)
- 原声大碟 -《仙剑奇侠传三·电视原声带》[MP3]
- linux应用程序注册表,如何打开 Linux 中 Windows 程序的注册表编辑器
- python中strip的使用