Spring 学习
Spring源码
IOC、AOP
困难:难坚持,方法
面试:
1、聊聊Spring
2、bean的生命周期
3、循环依赖
4、三级缓存
5、FactoryBean和BeanFactory
6、ApplicationContext 和BeanFactory的区别
7、设计模式
基石
IOC容器
一、IOC
bean --数据结构–map—三级缓存
kev-v数据格式 --》创建对象–》获取对象–》beanName的bean实例对象
创建对象的格式:
- new
- 工厂
- 反射
创建那些对象
context.getBean(Class,String)
bean初始化的过程
定义读取配置文件的规范(抽象接口)
BeanDefinition bean定义信息
BeanDefinitionReader
实例化bean(new 反射)
实例化、初始化区别 先实例化,后初始化,完整的bean对象
实例化 在堆中开辟一块空间属性都是默认值
初始化 给属性完成赋值操作
1、填充属性
BeanPostProcessor:before
2、执行初始化方法
BeanPostProcesssor:after
BeanFactory
反射的三种方式、先获取Class对象
Class clazz=Classs forName(“完全限定名”)
Class clazz=对象.getClass();
Class clazz=类.class;
Constructctor ctor=clazz.getDeclareConstructor();
Object obj=ctor.newinstance();
PostProcessor 增强器、 后置处理器 、扩展性
BeanFacoryPostProcessor
AOP 查看源码:BeanFacoryPostProcessor
动态代理
1、cglib
2、jdk
Spring 生命周期
创建的 通过反射 new 实例化bean, 填充属性值,BeanPostProcessor:before, 初始化bean,执行init方法
BeanPostProcessor:after,完整的bean对象
Environment
ENV
PROPERTIES
为了使用方便,在容器创建的时候会提前加载后系统的相关属性
加载到StandardEnvironment对象中,方便后续使用
如果我需要 在bean对象的创建过程中,详细了解每一个步骤完成的进度,我该怎么做?在不同的阶段要做不同的处理工作
应该怎么做
观察者模式监听器广播
AbstractApplicationContext
prepareRefresh()
- obtainFreshBeanfactory() 创建工厂
- beanDefinition 读取xml 文件
- prepareBeanFactory() 填充属性值
- postProcessorBeanFactory() 空方法,子类实现需要
- invokePostProcessorBeanFactory()
- registerBeanPostProcessor() 只是注册不执行
- initMessageSource 国际化
- initappliccationEventMulticaster() 多播器,方便发布监听事件
- registerListeners
- finishBeanFactoryInitialization()
getBean() doGetBean() createBean() doCreateBean() ConstStruct ctors.newinstance ,populateBean()填充属性 - fini
三级缓存
循环依赖
反射学习
实现
实现通过
创建一个Controller 类,给其设置一个私有的Service类,通过反射获取Controller的方法名称(set 方法名称)
将service 对象注入Controller
{
HelloController helloController=new HelloController();
Class extends HelloController> clazz = helloController.getClass();
// 创建对象
UserService userService=new UserService();
System.out.println(userService);
// 获取所有属性
Field serviceFiled = clazz.getDeclaredField(“userService”);
serviceFiled.setAccessible(true);
// 只有通过方法才能设置具体属性值
String name = serviceFiled.getName();
// 拼接方法的名称
name=name.substring(0,1).toUpperCase()+name.substring(1,name.length());
String setMethodName = “set” + name;
// 通过方法的属性注入对象
Method methond = clazz.getMethod(setMethodName, UserService.class);
methond.invoke(helloController,userService);
System.out.println(helloController.getUserService());
}
// 注解方式
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface AutoWired {
}
{
HelloController helloController=new HelloController();
Class extends HelloController> clazz = helloController.getClass();
Stream.of(clazz.getDeclaredFields()).forEach(field -> {
String name=field.getName();
AutoWired annotation=field.getAnnotation(AutoWired.class);
if(annotation!=null){
field.setAccessible(true);
Class> type = field.getType();
try {
Object object = type.newInstance();
field.set(helloController,object);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
});
System.out.println(helloController.getUserService());
}
Bean信息
xml
annotation
concurrenthashmap
IOC Container
Map
Map
BeanDefinitionReader(抽象层)
1、读取Bean定义信息
2、Bean定义信息init-method,destory-method,property
3、实例化后的对象
4、bean对象的实例化 Processor
5、为什么要添加name多的procesor?Spring是一个框架,作为框架,首先要考虑的就是扩展性!
可以自定义processor,来完成zhenggebean的实例化过程,增强某些功能
监听器
观察者模式
总结:想要称为一个框架,首先要考虑的一定是扩展性
Spring 提供了什么扩展性?
1、在对象创建之前添加某些功能
2、在容器初始化之前添加某些功能
3、在不同的阶段发出不同的事件,完成一些功能 (监听器,观察者模式)
4、抽象出一堆的接口来帮助扩展
5、面向接口编程
BeanFactory (模板)
beandifinitionReader
BeanFactoryPostProcessor 读取对应的bean的配置信息,但是发现需要人为的修改,此时可以在此处完成具体的操作
BeanPostProcessor
FactoryBean (做扩展) 面试常问俩者区别
Environment
AbstractapplicationContext



