Spring组成部分
1、核心容器Core、Beans、Context和Expression Language模块)
2、AOP(AOP定义例如方法拦截器和切点,从而将逻辑代码分开,降低它们之间的调合性)
3、数据存取整合(Data Access/Integration 层包含JDBC、ORM、J Ms(消息队列)和Transactio、 WEB(在web应用上下文基础上做了封装,简化了请求处理及参数绑定到域对象的工作)
5、TEST
核心容器
1、Core 模决包含Spring 框架基本的核心工具类,供其它组件使用,自己也可以直接调用2、Beans 模块包含访问配置文件、创建和管理bean以及进行( loc/DI)操作相关的所有类。核心类BeanFactory
3、Context Context模块继承了Beans的特性,提供了大量扩展,添加了对国际化、事件传播、资源加载和对Context创建的支持。核心类是AcationContext
4、Expression Language提供表达式语言容器实例化过程
示例代码
BeanfFactory bf= new XmlBeanFactory(new ClassPathResource (“beanFactory Test.xm’”)
MyTestBean bean=(MyTestBean)bf.getBean('rny TestBea");
简单描述
1.读取配置文件beanFactory Test.xml
2.根据beanFactory Test.xml中的类的全路径配置找到对应的类,并实例化放入容器中
3.从容器中拿到实例化后的实例。
Resource资源封装
Spring对不同来源的资源文件都直接或间接实现了Resource接口(顶级接口)文件(ileSystemResource)、Classpath资源(ClassPathResource)、URL资源(UrlResource)、InputStream资源(InputStreamResource)、Byte 数组(ByteArrayResource )等
初始化XmlBeanFactory
构造函数:new XmlBeanFactory(Resource resource),调用this.reader.loadBeanDefinitions(resour做了三件事:获取对XML文件的验证模式;加载XMLreader即XmlBeanDefinitionReader,在构造函数loadBeanDefinitions(resource)f(文件,并得到对应的Document ;根据返回的Document 注册Bean信息(提取元素中的id以及name属性,进一步解析其他所有属性并统一封装至GenericBeanDefinitior类型的实例中)。
BeanDefinition< bean>元素标签拥有class、scope、lazy-init…….等配置属性,BeanDefinition解析各种属性
则提供了相应的beanclass、scope、lazylnit属性,BeanDefinition和中的属性是——对应的scope:"singleton:单例;"prototype"多例:'request"将对象存到request域:"session"将对象存到sessionsingleton: true"单例"false"多例此属性与scope属性冲突,只能出现一个
abstract:“true”;表明此bean为抽象的
parent:"bean的id"指定继承某个bean的属性,不一定真的要实现类的继承 .abstract|和parent属性配合使用可以xml重复代码减少的方法
lazy-init:“true” "false"是否进行bean懒物加载仅适用于单例模式,区别在于在容器启动时自动加载bean还员一次使用时加载bean 一个非懒加载的bean初始化依赖了一个懒加载的bean,懒物加载的bean也会被立即初h始化一般个人开发可以设置为true提升项目启动速度实际应用时设置为false
autowire:"自动装配一共五个可选值.默认’no’ byName,by Type constructor defauBean的注册
将BeanDefinition注册到BeanDefinitionRegistry类型的实例registry中BeanDefinitionRegistry中有一个concurrentHashMap,以beanName为key,Beandefinition作为值
Bean的加载循环依赖解决:
1.通过构造器注入(比如A类的构造函数里调用了B类的方法B类的构造函数里调用了A类的方法)构成的循环依赖,此依赖是无法解决的,只能抛出BeancurrentlylnCreationException异常表示循环依赖。
2.通过setter方法依赖的类注入,处于单例模式的时候,可以通过三级缓存来解决循环依赖.比如A的setter方法依赖了类的方法,B类的setter方法依赖了A类的方法.
工厂根据默认构造函数将放入beanA的工厂放入三级缓存然后进行属性实例化,依赖了B,于是容器进行B的s例化根据B的构造函数实例化得到B,然后属性实例化,由于A类的工厂已经在三级缓存中,则调用A的工的(Bean方法得到A.至此,B类初始化完成然后A接着进行属性初始化即可.
这种解决相互引用的方式称为三级缓存的方式,即整个流程涉及到三个变量(都是Map)∶
singletonObjects∶一级缓存,存储beanName (key)和bean实例(value)之间的关系,这里存储的an实例是已经完全创建完成的bean实例
earlysingletonObjects:二级缓存,也是存储beanName和bean实例之间的关系,注意和singletonObjects的区别,这里存储的bean实例是没有创建完成的bean实例,即该bean还在创建过程中,为了解决循环引用的问题,将未创建完全的bean缓存起来。
singletonFactories:三级缓存,用于保存beanName和bean工厂之间的关系。当三级缓存创建bean成功后,会将bean放入二级缓存,并将beanName对应的beanFactory从singletonFactories中移除。
为什么bean为多例时不能解决循环应用问题?因为多例时不会对bean进行缓存也就没有未创建完成的bean可以预先使用
AOP(切面的织入advice就是在beanA工厂的getObject方法中进行的)
aware接口可让bean自身感受到容器自身
BeanPostProcessor也叫后置处理器,作用是在Bean对象在实例化和依赖注入完毕后,在显示调用初始方法(init-method)的前后添加我们自己的逻辑。注意是Bean实例化完毕后及依赖注入完成后触发的。
多个后置处理器我们可以在Spring配置文件中添加多个BeaPostProcessor(后置处理器)接口实现类,在认情况下Spring容器会根据后置处理器的定义顺序来依次调用。
在Spring机制中可以指定后置处理器调用顺序,通过让BeanPostProcessor接口实现类实现Order的getorder方法,该方法返回一整数,默认值为0,优先级最高,值越大优先级越低
客户定制的初始化方法除了我们熟知的使用配置init-method 外,还有使自定义的bean实现InitializingBean 接口,并在afterPropertiesSet 中实现自己的初始化业务逻辑。
同样也提供了销毁方法的扩展入口,对于销毁方法的扩展,除了我(们熟知的配置属性destroy-method方法外,用户还可以注册后处理器DestructionAwareBeanPostProcessor来统一处理bean 的销毁方法spring的提供的内置事件:
1》ConitextRefreshedEvent :ApplicationContext容器初始化或刷新触发该事件。此处说的初始化是指所有的bean被成功加载,后处理的bean被检测激活,所有的singleton
bean被预初始化,ApplicationContext容器已就绪可用。
2》ContextStartdEvent :当使用ApplicationContext的子接口ConfigurableApplicationContex控的start方法启动ApplicationContext容器时触发该事件。容器管理生命周期的bean实例将获得一定的启动信号,这在经常需要停止后重新启动的场合比较常见。
3》ContextClossedEvent :当使用ConfigurableApplicationContex接口的close()方法关闭ApplicationContext容器时触发该事件。
4》ContextStoppedEvent :当使用ConfigurableApplicationContex接口的stop0方法使Application Context容器停止时触发该事件。此处的"停止"意味着,容器管理生命周期的bean实例将获得一个指定的停止信号。被停止的spring 容器可以再次通过调用start方法重新启动。
5》RequestHandledEvent:Web相关的事件,只能应用于使用Dispatcherservlet的Web应用中。在使用spring作为前端的mvc控制器时,当处理完用户的请求时,系统会自动触发该事件。