这里写目录标题
- Spring从哪开始?
- Spring的基本运行
- BeanFactoryPostProcessor与BeanPostProcessor的区别
- BeanFactoryPostProcessor用来处理bean的定义信息BeanDefinition
- BeanPostProcessor用来处理Bean对象(包含实例化与初始化)
- Environment
Spring从哪开始?
- 聊聊spring
- 说明bean的生命周期
- 循环依赖
- 三级缓存
- FactoryBean和beanFactory
- ApplicationContext和BeanFactory的区别
- 设计模式
什么是Spring?
总 :spring认知
Spring是一个基础的框架(轻量级框架),同时给我们提供了bean的容器,用来帮助我们方便装载具体的bean对象,我们之前在使用对象的时候,必须要程序员自己创建,而现在我们只需要告诉容器有哪些对象,他会帮我们创建好,并且维护整个整体的生命周期,我们在Spring的技术之上还有SpringBoot、SpringCloud一系列扩展的技术框架,这个框架都是在Spring框架为基石的,在上面进行一些扩展开发。
分 ioc
Spring框架中有两个非常重要的特性 IOC 、AOP
IOC表示的是控制反转,原来是我们程序员自己创建对象,现在都交给Spring框架的IOC容器进行创建,管理Bean对象。
AOP表示面向切面编程, 一些用于更业务逻辑无关的代码我们可以通过AOP的方式进行实现,我们日常使用中日志、权限控制,统一上传> 文件参数校验等等都是通过AOP进行实现, 具体的业务逻辑该怎么写就怎么写,后面需要进行扩展的时候可以通过AOP里面的通知往具体
方法的前置、后置、中间、环绕等不同的环境里面添加具体的更业务无关的代码,完成我们具体的功能
Spring在一般情况下都分为两个部分
- IOC :控制反转,由Spring进行创建对象,实现层解耦
- AOP :面向切面变成,将工程代码与工具代码分离,实现主次解耦
谈到Spring,就一定会说到Spring容器也就是Ioc容器
IOC容器 : 承载某些或者具体的事务(Bean对象)
Spring的基本运行
Spring是如何进行创建对象的呢?
- 首先提前定义好我们需要的bean对象的描述信息(也就是我们application.xml配置好的文件)
- xml对于spring来说,类似于定义的读取文件的配置规范 (这里xml就是定义的规范)
- spring通过定义的xml文件规范格式拿到对应的bean定义信息BeanDefinition
- 解析这些信息,通过反射的方式实例化bean对象
- 然后初始化bean对象,得到一个完整的bean对象
接口 自上向下 不考虑子类实现,遵循接口规范,自上向下
抽象类 自下向上 【三个类有共同特点】生成抽象类,考虑子类之间共性, 自下向上
-
BeanDefinition
上述Spring的基本运行中,你所有的定义描述信息都在XML文件里面,如何读取呢?
当然通过 new ClassPathXmlApplicationContext(“applicationcontext.xml”)
该代码就是读取XML文件,而Bean对象信息就在xml里面,Bean的定义信息通过XML读取到了IOC容器中,此时,IOC的容器出现了bean的定义信息,并赋予了一个名字:BeanDefinition -
BeanDefinitionReader
BeanDefinitionReader :规范信息的接口
BeanDefinitionReader 的作用是读取 Spring 配置文件中的内容,将其转换为 IoC 容器内部的数据结构:BeanDefinition -
反射
- 获取Class对象
- Class clazz = Class.forName(“完全限定名”);
- Class clazz = 对象.getClass();
- Class clazz = 类型.Class;
- 获取构造器
- Constructor ctor = clazz.getDeclaredConstructor();
- 获取对象
- Object obj = ctor.newInstance();
- 获取Class对象
注意点 :实例化与初始化的区别
-
增强器
为了Spring扩展实现
例如下面加载数据库链接,${}内的变量是如何替换的呢?这里就用到了扩展
<!--配置数据库连接池--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/><property name="driverClassName" value="${jdbc.driverClass}"/></bean>
BeanFactoryPostProcessor与BeanPostProcessor的区别
BeanFactoryPostProcessor用来处理bean的定义信息BeanDefinition
BeanPostProcessor用来处理Bean对象(包含实例化与初始化)
BeanFactoryPostProcessor用来处理bean的定义信息BeanDefinition
现在占位符还存在
调用invokeBeanFactoryPostProcessors 占位符已经替换了
自己扩展,实现BeanFactoryPostProcessor,在创建对象前修改bean的定义信息BeanDefinition
BeanPostProcessor用来处理Bean对象(包含实例化与初始化)
实现AOP,需要用到动态代理
-
动态代理
- ObjenesisCglibAopProxy
- JdkDynamicAopProxy
postProcessAfterInitialization方法会执行wrapIfNecessary,最终会执行到createAopProxy方法
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {if (bean != null) {Object cacheKey = this.getCacheKey(bean.getClass(), beanName);if (this.earlyProxyReferences.remove(cacheKey) != bean) {return this.wrapIfNecessary(bean, beanName, cacheKey);}}return bean;}protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {return bean;} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);if (specificInterceptors != DO_NOT_PROXY) {this.advisedBeans.put(cacheKey, Boolean.TRUE);Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;} else {this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}} else {this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}}
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {return new JdkDynamicAopProxy(config);} else {Class<?> targetClass = config.getTargetClass();if (targetClass == null) {throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");} else {return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));}}}
Environment
扩展 SpringBoot