斯普林
Spring IOC主要分为三个部分。定位,加载,初始化
基本概念:
33558www.Sina.com//--springbean的创建采用了工厂模型。 BeanFactory定义了IOC容器的基本规范,具体实现由子类补充。 主要子类是ListableBeanFactory。 通过类图,HierarchicalBeanFactory和AutowireCapableBeanFactory最终发现缺省实现类是DefaultListableBeanFactory。 定义多级接口主要是为了满足各种需求,功能扩展性强
Spring提供了许多IOC容器的实现,如GenericApplicationContext、ClassPathXmlApplication等
ApplicationContext是Spring提供的高级IOC容器,除了提供IOC容器的基本功能外,还提供其他服务
1 )支持信息源,可国际化
2 )访问资源(实现ResourcePatternResolver接口) )
3:APP事件支持
BeanFactory--SpringIOC容器用于管理我们定义的各种Bean对象及其相互关系,并描述它们之间的关系
BeanDefinition--Bean的分析过程很复杂,需要确保beanDefinitionReader具有足够的灵活性才能分析Spring中的配置文件
基于XML的IOC容器初始化的总体流程图:
最终,IOC容器是beandefinitionmap,它是用于存储BeanDefinition的映射
用Annotation初始化
1 )要直接在容器中注册注释Bean,请在初始化容器时进行注册,或者在创建容器后手动调用注册方法来注册容器,然后手动更新容器,以便容器可以处理这些注释Bean
2 :扫描中指定的包及其子包下的所有类
注释指定初始化容器时自动扫描的路径。 如果创建了容器,并在指定路径中动态添加了注释Bean,则必须手动调用容器扫描的方法来手动更新容器,以便容器能够处理注册的Bean
总结:
1 :在容器实现中按错了已初始化条目的refresh ()调用
2 )使用资源加载器定位资源文件,并使用BeanDefinitionReader分析定义信息和注册bean信息。 获得BeanDefintion对象后,需要在IOC容器中注册它。 实际上,它是存储BeanDefinition对象的映射
BeanDefinitionReader
1 :用户第一次调用GetBean )时
2 )用户配置lazy_init=false属性,懒惰加载,默认初始化时进行依赖注入,如果配置为true,则在使用过程中进行依赖注入
获取Bean的条目,并调用BeanFactory的getBean (),然后调用AbstractBeanFactory的doGetBean )方法
开始实例化,并在abstractautowirecapablebeanfactory (类的createBean中实例化
选择Bean实例化策略,然后根据指定的初始化策略,使用简单工厂、工厂方法或容器的自动组装特性生成Java实例对象
执行Bean实例化,如果Bean包含方法,则使用JDK反射实例化该方法,否则使用CGLIB
要依赖于注入,请先调用createBeanInstance ()方法生成Bean中包含的Java实例对象,然后调用populateBean )方法向Bean注入属性。 如果需要对属性值进行类型转换,则在将其注入到实例对象的目标之前,必须根据属性值分析引用对象
DI:依赖注册:
1: Spring AOP:切面(Aspect ) -在关注点模块化中使用Aspect
2:通知--对于由连接点生成的操作,一个连接点可以包含多个advise(beforeadvice,AfterAdvice,AroundAd )
3:切口---与连接点断言一致,在AOP上通知和一个切口式相关,切面的所有通知处
关注的连击点,都由切入点表达式决定4:目标对象(Target Object)-->被一个或者多个切面所通知的对象
5:AOP代理--->默认情况下TargetObject实现了接口则采用JDK,否则使用CGLIB,也可以强制使用CGLIB代理,将proxy-target-class设置为true
BeanPostProcessor后置处理器,这个Bean后置处理器是一个监听器,可以监听容器触发的Bean声明周期事件,后置处理器向容器注册以后,容器中管理的Bean就具备了接受IOC容器事件回调的能力,该接口中有两个方法postProcessBeforeInitialization()和postProcessAfterInitialization()两个方法
1:在实例化Bean对象时候,为容器产生的Bean实例对象添加BeanPostProcessor后置处理器,初始化操作由实现的子类实现,例如AOP切面织入使用了AbstractAutoProxyCreator类
2: 选择代理策略,在postProcessAfterInitialization()方法中,通过wrapIfNecessary()来选择JDK代理还是CGLIB代理
3:如果使用JDK动态代理,则在织入时候首先获取到此方法上的通知链(Interceptor chain),如果有通知则应用通知,如果没有通知,则反射执行JoinPoint
获取通知链方式:获取Advisor列表,然后将判断此Advisor是否能应用到目标方法method上,满足条件的Advisor通过AdvisorAdapter转换成Interceptor列表返回
SpringMVC
九大组件:
1:HandlerMapping-->用来查找Handler,在请求到达后,通过该HandlerMapping找到请求相应的处理器Handler和Interceptors
2:HandlerAdapters-->SpringMVC中的Handler可以是任意形式的,只要能处理请求就可以,但是请求交给Servlet时候,需要转换成统一的格式
3:HandlerExceptionResolvers-->处理Handler过程中产生的异常情况的组件,只解析对请求做处理阶段产生的异常,渲染阶段异常不处理
4:ViewResolvers-->将String类型的视图名和Locale解析为View类型的视图
5:RequestToViewNameTranslator-->从Request中获取viewName
6:LocaleResolver---->LocaleResolver用于从request中解析出Locale
7:ThemeResolver---->用于解析主题
8:MultipartResolver--->处理上传文件请求,将普通的Request包装成MultipartHttpServletRequest实现
9:FlashMapManager
SpringBean初始化之后回调方法的执行顺序:
初始化:构造器-->@PostConstruct--->InitializingBean接口-->initMethod()
销毁:@PreDestroy-->DisposableBean--->destroyMethod
IOC容器对Bean的生命周期:
1:通过构造器或者工厂方法创建Bean实例
2:为Bean设置属性值和对其他bean的依赖
3:将bean实例传递给Bean后置处理器的postProcessBeforeInitialization方法
4:调用Bean的初始化方法initMethod
5:将Bean实例传递给Bean后置处理器的postProcessAfterInitializaation方法
6:使用Bean
7:容器关闭时候调用Bean的destroy-method方法
Spring的循环依赖:
采用三级缓存来解决循环依赖
当采用一级缓存时候,已经初始化好的Bean和未初始化好的Bean都在一个容器中,当有多个线程来访问时候会造成空指针异常,如果采用二级缓存时候,初始化好的Bean和未初始化好的Bean分开,可以解决大部分问题,但是如果该Bean是被代理的,会导致在缓存中同一个实例有不同的对象,而整个Bean又是单例的,所以采用三级缓存来解决循环依赖问题