Spring(容器框架)
1.实现了工厂模式的工厂类,通过<bean>元素配置于创建实例对象的类名和实例对象的属性;
2.IOC依赖注入(控制反转);
3.AOP:系统中很多不相干的类的方法,在这些方法中要加入某种系统功能的代码,例如加入日志,事务,加入权限判断,加入异常处理,这种应用成为AOP。
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理。JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler
接口和Proxy
类。
如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成某个类的子类,注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final
,那么它是无法使用CGLIB做动态代理的。
SpringMVC(MVC模式的Web框架)
第一步:发起请求到前端控制器(DispatcherServlet)
第二步:前端控制器请求HandlerMapping查找 Handler可以根据xml配置、注解进行查找
第三步:处理器映射器HandlerMapping向前端控制器返回Handler
第四步:前端控制器调用处理器适配器去执行Handler
第五步:处理器适配器去执行Handler
第六步:Handler执行完成给适配器返回ModelAndView
第七步:处理器适配器向前端控制器返回ModelAndView,ModelAndView是springmvc框架的一个底层对象,包括Model和view
第八步:前端控制器请求视图解析器去进行视图解析,根据逻辑视图名解析成真正的视图(jsp)
第九步:视图解析器向前端控制器返回View
第十步:前端控制器进行视图渲染视图渲染将模型数据(在ModelAndView对象中)填充到request域
第十一步:前端控制器向用户响应结果
Spring bean的生命周期
核心方法都在doCreatBean()方法里面
- 实例化 Instantiation——createBeanInstance()
- 属性赋值 Populate——populateBean()
- 初始化 Initialization——initializeBean()
- 销毁 Destruction
// 忽略了无关代码
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
// 实例化阶段!
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 属性赋值阶段!
populateBean(beanName, mbd, instanceWrapper);
// 初始化阶段!
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
spring IOC 容器启动(bean加载初始化)过程
1.读取配置文件,解析标签,把配置信息提取出来成为一个个的beanDefinition,实际上就是bean在代码里的实现。
2.bean的注册,也就是把beanDefinition存到beanDefinitionMap(concurrentHashMap)里面,bean容器也初始化完成。
3.初始化所有单例的bean(lazy-init除外),核心方法doGetBean(),doCreatBean()。doGetBean()方法会先获取bean的实际beanName,然后从缓存中获取对应的bean,获取到的bean可能是不完整的,还需要调用getObjectForBeanInstance()方法得到完整的bean。如果缓存里面没有获取到bean,先判断是不是原型bean,是的话直接抛出异常,否则就去父容器里获取单例bean。处理bean的依赖,先创建依赖的bean,再创建bean的实例,接下来执行doCreateBean()方法。doCreateBean()包含了解决循环依赖问题的代码,主要是对bean进行实际的实例化过程,(如果使用无参构造函数构造实例,会判断是否存在方法覆写,不存在用java反射实例化,存在则用cglib实例化),实例化完成之后进行bean属性的注入,最后是其他方法的回调。