ArrayList与LinkdList的区别?
ArrayList:基于动态数组,连续内存存储,适合下标访问(随机访问)
LinkedList:基于链表,存储在分散的内存中,适合做数据的插入,删除,不适合查询,必须使用iterator遍历
-
Spring是什么?
轻量级开源的J2EE框架;
是一个容器框架,用来装JavaBean(Java对象);
中间层框架,起一个连接作用(比如说吧struct和hibernate粘合在一起运用);
让我们的企业开发更快,更简洁。
轻量级的控制反转(IOC)和面向切面的(AOP)框架
- 轻量级:从大小和开销方面而言Spring都是轻量级的
- IOC:通过控制反转(ioc)的技术来达到松耦合的目的
- AOP:分离应用的业务逻辑和系统级服务进行内聚式的开发
- 容器:包含并管理应用对象(Bean)的配置和生命周期
- 框架:简单的组件配置,组合成复杂的应用
Aop的理解?
将程序中的交叉业务逻辑(比如安全,日志,事务等),封装成一个切面,然后注入到目标对象(具体业务逻辑)中去。
Aop可以对某个对象或某些对象的功能进行增强,比如对象中的方法进行增强,可以在执行某个方法之前、或之后执行额外的做一些事情。
Ioc的理解?
容器概念:ioc就是一个容器,实际上就是一个map(key,value),里面存的是各种对象(在xml里配置的bean节点,@repository,@service,@controller,@component)
在项目启动的时候会读取配置文件里的bean节点,根据全限定类名使用反射创建对象放到map里,或者扫描到打上上述注解的类通过反射创建对象放到map里。
然后系统启动的时候读取xml节点的ref属性根据id,或者根据注解(@autowired,@resource)在代码里需要用到里面的对象时,通过DI注入
控制反转:
引入Ioc容器之前:对象A依赖对象B,主动创建对象B
引入ioc容器之后:对象A需要对象B,ioc容器主动创建对象B注入到对象A需要的地方
控制反转:前后对比,对象A获取依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒。
对象的控制权全部上缴给"第三方"IOC容器,IOC容器成为了系统的关键核心,关联系统中的所有对象一起发挥作用。
依赖注入:实现IOC的方法,有IOC容器在运行期间,动态将某种依赖关系注入到对象之中。
Bean
Bean是什么?
bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。
-
基于 XML 的配置文件
-
基于注解的配置
- 基于 Java 的配置
BeanFactory和ApplicationContext有什么区别?
ApplicationContext是BeanFactory的子接口
ApplicationContext提供更完整的功能:
- 继承了MessageSource,因此支持国际化。
- 统一的资源文件访问形式。
- 提供在监听器中注册bean的事件。
- 同时加载多个配置文件。
- 载入多个(有继承关系)上下文,使得每一个上下文都专注一个特定的层次,比如应用的web层。
- BeanFactory采用延迟加载形式注入Bean,即只有在使用某个Bean(调用getBean()),才对该Bean进行加载实例化。启动后只有在使用的时候才能发现存在的Spring的配置问题,
- ApplicationContext,容器启动时,一次性创建了所有的Bean(启动时就可以发现Spring中存在的配置错误,有利于检查所依赖属性是否注入),Application启动后预载入所有的单实例Bean,需要的时候不用等待。
- Application占用内存不足,程序配置Bean较多时,启动越慢。
- BeanFactory通常以编程方式创建,ApplicationContext可以以声明的方式启动,如使用ContextLoader
- 都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,区别:BeanFactory需要手动注册,ApplicationContext则是自动注册
BeanPostProcessor接口回调对应的主体是bean,其可以在bean实例化以后但是在调用其初始化方法前后进行回调以达到对bean进行处理的效果。
BeanFactoryPostProcessor的主体是BeanFactory,并且该接口中只定义了一个方法,其将会在ApplicationContext内部的BeanFactory加载完bean的定义后,但是在对应的bean实例化之前进行回调。所以通常我们可以通过实现该接口来对实例化之前的bean定义进行修改。
Bean生命周期?
- 解析类得到BeanDefinition
- 如果有多个构造函数,则要推断构造方法
- 实例化得到一个对象
- 对对象中加了@Autowired注解的属性进行属性填充
- 回调Aware方法,比如BeanNameAware,BeanFactoryAware(
Aware
接口也是为了能够感知到自身的一些属性) - 调用BeanPostProcessor的初始化前的方法
- 调用初始化方法init
- 调用BeanPostFactoryProcessor初始后的方法,在这里会进行Aop
- 如果创建的Bean是单例则会放入单例池
- 使用bean
- Spring容器关闭时调用DisposableBean的Destory方法
Bean作用域
singleton | 默认:每个容器只有一个bean的实例,单例的模式由BeanFactory自身来维护。该对象的生命周期与Spring Ioc容器一致(第一次被注入时创建) |
---|---|
prototype | 原型模式,为每一个bean请求创建一个实例。在每次注入时都会创建一个新的对象 |
request | bean被定义为在每个HTTP请求中创建一个单例对象,也就是说单个请求中都会复用这一个单例对象 |
session | 与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效 |
application | bean被定义为在servletContext的声明周期中复用一个单例对象 |
websocket | bean被定义为在websocket的生命周期复用一个单例对象 |
global-session | 全局作用域 |
Spring单例Bean是线程安全?
非线程安全,没有进行多线程封装处理。
怎么保证?改变bean的作用域,把singleton改为prototype,相当于每次请求是new Bean()