Spring
容器
生态
IOC 原来要去new 对象,由容器创建,并进行管理和控制
AOP业务逻辑无关的代码,日志,权限控制,消息通知,前置,后置环绕等方法
IOC如何实现?
容器:bean 通过Map<k,v>存储
获取bean:context.getBean(Person.class)
如何注册到容器中?
xml,注解:放
------ 接口 BeanDefinitionReader-------
约束和规范:可扩展不同格式的配置文件,properties,yml...
扩展性
----- BeanDefinitionReader ---------
解析xml: 读文件 IO流inputStream,SAX,dom4j--> document->node,k,v--> 放到某一个对象中去
解析注解:通过反射 获取Class对象,通过getAnnotation,有注解的创建对象
解析完成后BeanDefinition:bean的定义信息,放到 Map<>中
bean的定义信息
创建bean对象:通过反射:反射只有在创建对象比较多的时候才会比较慢
BeanFactoryPostProcess接口,可以替换占位符等
BeanPostProcess:Bean
1)获取class对象
Class clazz = Class.forName(包名+类名)
Class clazz = 对象.getClass()
Class clazz = 类名.class()
2)获取构造器
Constructor ctot = clazz.getDeclaredConstrctor()
3)创建对象
Object obj = ctor.newInstance()
使用bean对象:
销毁bean对象:
PostProcess:后置处理器/增强器:提供某些额外的扩展功能:
BeanFactoryPostProcessor:操作对象不同:BeanFactory:访问容器的根接口, ApplicationContext是他的子接口,可以通过BeanFactory(可以看成容器)修改对象,可以通过
(BeanDefinitionRegistryPostProcessor:
@ComponentScan @Import@ImportResource : 导入额外的对象)
实现BeanFactoryPostProcess可以替换Bean中的属性值,@Order(100)指定顺序 日常业务开发时用不到,二次开发时会需要用到
BeanFactoryPostProcess接口,可以替换占位符等
BeanPostProcess:Bean
接口和抽象类的区别
接口:自上向下,定义方法,不需要考虑具体子类实现
抽象类:单继承,自下向上,需要考虑子类共性,抽取共性提取抽象类
模板方法设计模式:onRefresh:初始化嵌入式tomcat
bean的生命周期:13个步骤
实例化bean对象
设置对象属性
检查Aware相关接口并设置相关依赖
bean的生命周期:从对象的创建,使用,销毁的过程
1)实例化:在堆空间中申请空间,此时对象的属性值一般是默认值,反射创建对象的过程 调用的方法名字 createBeanInstance:反射创建对象
2)初始化:
属性赋值
2-1 属性赋值:方法:populateBean:(填充Bean对象)set方法完成赋值操作
2-2 容器赋值:在一个对象中引用 BeanFactory,ApplicationContext,Environment等容器对象的时候, 需要实现Aware接口来统一给容器对象赋值,每个容器有自己对应的Aware,如BeanFactoryAware,ApplicationContextAware。
方法: invockAwareMethods
@Data
public class Dog implements BeanFactoryAware,ApplicationContextAware{
privite in id;
privite String name;
privite BeanFactory beanFactory;
privite ApplicationContext applicationContext;
privite Environment environment;
// 谁在什么时候调用这些方法呢?
// 容器调用,需要给出一个统一的标识,然后在统一的地方进行处理。
/*
定义一个aware接口
if(object instanceOf Aware){
if(object instanceOf BeanFactoryAware){setBeanFactory();}
if(object instanceOf ApplicationContextAware){setApplicationContext();}
...
}
*/
public BeanFactory getBeanFactory (){
return beanFactory;
}
public void afterPropertiesSet() throws Exception{
...
}
}
----- Q: 执行到此步骤之后,对象的创建和属性的赋值都完成了,那么此时对象是否可以直接拿来使用?
----- A:理论上是可以的,但是注意Spring要考虑扩展性。
初始化: 2-3 到 2-5 做bean对象的扩展实现
BeanPostProcessor -- AOP--动态代理:jdk,cglib
AOP是IOC整体流程(指bean的创建过程)中的一个扩展点
2-3 执行前置处理方法
2-4 执行初始化方法 -- invockInitMethods
2-5 执行后置处理方法
3 使用bean对象
4 销毁bean对象 调用context.close() 才会销毁,一般我们都直接关闭程序,没有销毁的步骤。
循环依赖:三级缓存: 3个Map结构
Spring中的bean对象按使用者分为:自定义对象,容器对象(BeanFactory,ApplicationContext,Environment)
BeanFactory:bean对象创建的整体流程,不是指根接口,bean的生命周期是一个标准化的
流程: 流水线
FactoryBean:用来创建bean对象: 自定义,私人订制
判断是否单例,返回对象类型,创建对象