一.回顾
关于上次面试汇总的问题中的spring相关的问题,这篇文章就其中的一部分来进行回答和记录,其中标出的部分为面试中重点问到的,应重点掌握.首先来对其中的问题做一下回顾
- springIOC容器中有两个类A,B相互注入会有什么情况发生?有没有什么问题?
- spring的bean的生命周期?详细描述一下
二.对问题进行分析总结
- IOC和DI ioc 反转资源获取的方向,传统是组件向容器请求查找获取资源,容器适时返回资源,应用了IOC之后,则是容器主动的将资源推送给他所管理的组件,组件需要做的仅仅是选取合适的方式来取得资源,查找的被动形式
- DI 组件以一种预先定义好的方式,(setter,constructor)来接受容器的注入;相对于IOC,这种表述更为直接;
- 循环引用 在A , B两个类交给spring容器处理,通过setter注入是没有问题,但是通过构造器注入,会出现循环引用的问题, 只要xml出现循环引用,application.xml获取就会报错
- 配置bean
- 在xml里面进行配置,相当简单
- 可以通过name获取,也可以通过type获取
- 通过type获取有缺点,必须要该类为唯一的
- 属性注入 setter方法注入
- 构造器注入 constructor注入
- 根据顺序来配置,index属性,但是会有问题,同类型的两个构造器会分不清楚
- 根据参数的类型来配置,type属性
- 一些注意的细节
- spring自动将字符串转为int类型
- 如何含有特殊字符,可以使用特殊字符标签来标记
- 如果有有参构造,必须显式声明无参构造;
- 可以声明内部bean,但是不能被外部其他类引用
- 引用的实体对象,不赋值,默认为null;
- list ,map,properties可以直接在xml中配置,注入
- properties类是java.util下面的hashtable 的子类 -** 自动装配**
- byname(根据setter风格自动装配,如果有符合的自动装配,没有则不装配)
- byType 根据类的属性来匹配 byType有个缺点,存在多个相同类的时候,会报错,没有byName好用,
- 平时很少使用autowired,远不如清晰明确的配置文档说明更加清楚;
- 配置bean之间的关系
- bean配置之间的继承, parent属性
- 父类bean可以设置为abstract=true,作为模版来使用.且不能被实例化,abstract属性不会被继承;
- bean之间的依赖关系 depends-on属性
- 使用该属性来配置类之间的依赖关系,需要在xml中配置好前置依赖的bean,否则会报错
- 配置bean的作用域 scope 属性
- 默认作用为单例的, singleton,整个容器的生命周期内都是一个实例,改为 prototype,则改为多例,
- singleton类型是容器初始化时候,就已经实例化对象;
- prototype类型是容器初始化的时候不创建,在 需要的时候,每次请求都创建一个新的bean实例; (eg:strtus2 action指定prototype)
- request
- session
- spring引入外部配置文件
- spring提供了一个propertyholderConfigurer的beanfactory后置处理器,这个处理器允许用户将bean配置的部分内容外移到属性文件当中去,在bean配置文件中使用${var}形式的量,propertyholderConfigurer从属性文件里面加载属性,来替换变量
- spring2.0中需要注册这个propertyholderConfigurer类,在spring2.5之后,可直接通过Context:property-placeholder元素简化,来引入本地的外置配置文件 优点,降低修改底层数据库的修改成本,只需要修改配置文件就可以了
- spring两种配置ioc容器的实现
- beanfactory
- applicationContext提供了更多高级特性,是beanfactory的子接口; applicationContext是面向框架的开发者,而beanfactory是面向spring本身的;
- 这里主要看一下applicationContext 的实现类有那几个
- ConfigurableApplicationContext(新加两个方法,refresh,和close,让ApplicationContext有启动,刷新,关闭上下文的能力)
- classpathxmlApplicationContext(在类路径下找xml配置文件)
- fileSystemXmlApplicationContext(在文件系统里面找配置文件)
- ApplicationContext在初始化上下文时候,就实例化所有的单例的bean,
- WebApplicationcont是专门为web应用准备的,运行从web 的根目录的路径中完成初始化工作;
- 这里主要看一下applicationContext 的实现类有那几个
- spring的spEL语言
- 支持运行时查询和操作对象的强大的表达式语言
- spEL使用#{}作为限定符,所有在大括号里面的都认为是spEL
- 为bean的动态赋值提供了便利
- 使用spEL引用类的静态属性 value = #{T(java.lang.Math).PI * 80}}
- 使用spEL来应用其他的bean value =#{otherBean }
- 使用spEL来应用其他的bean的属性 value=#{otherbean.attribute}
- spEL中应用运算符 '#{otherbean.attribute>100?优秀:良好}
- springIOC容器中bean 的生命周期 spring允许在bean生命周期的特定点执行定制的任务
- 管理的过程如下:
- 通过构造器或工程方法创建bean实例
- 为bean实例设置属性或者对其他bean 的引用
- 调用bean 的初始化方法( init-method)
- 使用bean
- 容器关闭时,调用bean的销毁方法(destory-method)
- 在bean 的声明里, init-method 和 destory-method属性,分别为bean指定初始化和销毁方法
- spring提供了bean的后置处理器,允许在调用初始化方法的前后,对bean进行额外的处理,
- bean后置处理器对IOC容器里的所有bean实例逐一处理,而非单一实例
- 自己实现BeanPostProcessor接口,并具体提供postProcessBeforeInitialization(Object bean,String beanName),postProcessAfterInitialization(Object bean,String beanName)两个方法的实现: bean:bean实例本身, beanName:IOC容器配置的bean实例的名字 返回值:是实际上返回给用户的那个bean,可以在以上的两个方法中修改返回的bean
- 添加了bean 的后置处理器之后,bean的生命周期流程如下
- 通过构造器或工程方法创建bean实例
- 为bean实例设置属性或者对其他bean 的引用
- 将bean实例传递给bean后置处理器的 postProcessBeforeInitialization方法
- 调用bean 的初始化方法( init-method)
- 将bean实例传递给bean后置处理器的postProcessAfterInitialization方法
- 使用bean
- 容器关闭时,调用bean的销毁方法(destory-method)
- 管理的过程如下:
三.总结
以上内容对spring的ioc容器中的循环引用,和bean的生命周期做了总结,方便以后自己的回顾和总结,对spring的关键部分的代码做了剖析和demo测试,理解加深了记忆,希望自己再接再厉,坚持记录下去. ps:原来是使用石墨记录的,贴到简书,markdown语法貌似有点出入,后续文章慢慢改正过来.