一, 什么是 Spring 的依赖注入, 有哪些方法进行依赖注入
?????? 依赖注入是 IoC 的一个方法, 就是调用者不用创建对象, 只需要描述对象如何创建, 描述哪些组件需要哪些服务, 之后 IoC 容器把他们组装起来.
?????? 构造器依赖注入: 通过容器触发一个类的构造器来实现, 该类有一系列参数, 每一个参数代表一个对其他类的依赖.
??????setter 方法依赖注入: 容器在实例化 bean 后, 调用 bean 的 setter 方法, 即实现基于 setter 的依赖注入.
二, 在 Spring 中如何注入一个 java 集合?
??????Spring 提供以下几种集合的配置元素:
??????<list > 类型用于注入一列值, 允许有相同的值
??????<set > 类型用于注入一组值, 不允许有相同的值
??????<map > 类型用于注入一组键值对, 键和值都可以为任意类型
??????<props > 类型用于注入一组键值对, 键和值都只能为 String 类型
- <property name="excludeUrls">
- <list>
- <value>/jsp</value>
- <value>/plat</value>
- </list>
- </property>
三, Spring 初始化 bean 的时机
??????1, 使用 BeanFactory 作为 Spring Bean 的工厂类时, 所有的 Bean 都会在第一次使用时 (getBean) 初始化
??????2, 使用 ApplicationContext 作为 SpringBean 的工厂类时
??????a,bean 的 scope 是 singleton 时, 且 lazy-init 为 false 时(默认为 false),ApplicationContext 启动时就会初始化, 并将实例化的 bean 放在一个 map 结构的缓存中, 下次再使用这个 bean 时, 直接从缓存中取
??????b,bean 的 scope 是 singleton 时, 且 lazy-init 为 true 时, 则该 bean 的实例化是在该 bean 第一次使用时 (getBean) 进行实例化
??????c,bean 的 scope 是 prototype 时, 则该 bean 的实例化是在该 bean 第一次使用时 (getBean) 进行实例化
四, Spring 如何解决循环依赖
??????1, 构造器参数循环依赖 - 无解. Spring 把正在创建的 Bean 标示符放在 "当前创建 bean 池" 中, A 依赖 B,B 依赖 C,C 依赖 A, 创建 A, 把 A 放在池中去创建 B.., 创建 C 时发现 A 已经在池中, 就会报错.
??????2,field 属性注入依赖, 单例模式 - 有解. Spring 先用构造器实例化对象, 此时 Spring 会将实例化结束的对象放在 Map 中, 并提供了获取这个未设置属性的实例化对象引用的方法. Spring 实例化 A,B,C 后紧接着去设置对象属性, A 依赖 B, 从 Map 中取出 B 的对象, 依此解决循环依赖.
??????3,field 属性注入依赖, 原型模式 - 无解. Prototype 作用的 Bean,Spring 容器无法完成依赖注入, 因为 prototype 作用对象, Spring 不会进行缓存, 无法提前暴露一个创建中的 Bean.
参考: https://www.cnblogs.com/tiger-fu/p/8961361.html https://www.cnblogs.com/tiger-fu/p/8961361.html
五, SpringMVC 核心处理流程
??????1,DispatcherServlet 前端控制器接收发过来的请求, 交给 HandlerMapping 处理器映射器
??????2,HandlerMapping 处理器映射器, 根据请求路径找到相应的 HandlerAdapter 处理器适配器(处理器适配器就是那些拦截器或 Controller)
??????3,HandlerAdapter 处理器适配器, 处理一些功能请求, 返回一个 ModelAndView 对象(包括模型数据, 逻辑视图名)
??????4,ViewResolver 视图解析器, 先根据 ModelAndView 中设置的 View 解析具体视图
??????5, 然后再将 Model 模型中的数据渲染到 View 上
?????? 这些过程都是以 DispatcherServlet 为中轴线进行的
六, SpringBean 的生命周期
??????Spring 容器中的 bean 的完整生命周期一共分为十一步完成.
??????1.bean 对象的实例化
??????2. 封装属性, 也就是设置 properties 中的属性值
??????3. 如果 bean 实现了 BeanNameAware, 则执行 setBeanName 方法, 也就是 bean 中的 id 值
??????4. 如果实现 BeanFactoryAware 或者 ApplicationContextAware , 需要设置 setBeanFactory 或者上下文对象 setApplicationContext
??????5. 如果存在类实现 BeanPostProcessor 后处理 bean, 执行 postProcessBeforeInitialization, 可以在初始化之前执行一些方法
??????6. 如果 bean 实现了 InitializingBean, 则执行 afterPropertiesSet, 执行属性设置之后的操作
??????7. 调用 < bean init-method="">执行指定的初始化方法
??????8. 如果存在类实现 BeanPostProcessor 则执行 postProcessAfterInitialization, 执行初始化之后的操作
??????9. 执行自身的业务方法
??????10. 如果 bean 实现了 DisposableBean, 则执行 spring 的的销毁方法
??????11. 调用 < bean destory-method="">执行自定义的销毁方法.
?????? 第五步和第八步可以结合 aop, 在初始化执行之前或者执行之后执行一些操作.
七, 说一下 Spring 中 Bean 的作用域
??????singleton: Spring 默认的作用域, springIOC 容器中只会存在一个共享的 Bean 实例
??????prototype: 每次从 spring 容器获取 bean 时都会创建并返回一个新的实例, 每个 bean 都有自己的属性和状态
??????reqeust: 在一次 http 请求中, 容器返回该 bean 的同一个实例, 该 bean 仅在 http request 中有效, 不同的 http request 会产生新的 bean
??????session: 在一次 http session 请求中, 容器返回该 bean 的同一个实例, 该 bean 仅在 session 中有效, 不同的 session 会产生新的 bean
??????global session: 在一个全局的 http session 中, 容器会返回同一个实例, 仅在使用 portlet context 时有效
八, Spring 框架中都用到了哪些设计模式
?????? 单例模式: Spring 配置文件中定义的 bean 默认为单例模式
?????? 工厂模式: BeanFactory 用来创建对象的实例
?????? 代理模式: 在 AOP 和 remoting 中用的比较多
?????? 依赖注入模式: 贯穿 BeanFactory/ApplicationContext 接口的核心概念
?????? 模板方法模式: 用来解决代码重复问题
九, BeanFactory 和 ApplicationContext 的区别
??????1,BeanFactory 和 ApplicationContext 都是接口, ApplicationContext 继承了 BeanFactory
??????2,BeanFactory 是 Spring 中最底层的接口, 提供了最简单的容器功能, 只提供了实例化对象和拿对象的功能. ApplicationContext 是 Spring 更高级的容器, 提供了更多的有用功能.
??????3, 加载方式的区别: BeanFactory 采用的延迟加载的方式注入 bean,ApplicationContext 对于单例模式的 bean 在 IoC 容器启动的时候就一次性创建所有的 bean, 好处是可以马上发现 Spring 配置文件中的错误, 坏处是造成浪费.
??????4,ApplicationContext 提供的额外的功能: 国际化的功能, 消息发送, 响应机制, 统一加载资源的功能, 强大的事件机制, 对 web 应用的支持等等.
十, ApplicationContext 的通常实现有哪些
??????FileSystemXmlApplicationContext:Spring 容器通过 xml 文件的全路径, 从一个 xml 文件中加载 bean 的定义, 如
??????ApplicationContext context = new FileSystemXmlApplicationContext("/src/main/resources/bean.xml");
??????ClassPathXmlApplicationContext:Spring 容器从 classpath 下的 xml 文件中加载 beans 的定义
??????ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
??????WebXmlApplicationContext:Spring 容器加载一个 xml 文件, 该文件定义了 Web 应用的所有 beans.
十一, Spring 的优点
??????1, 降低了组件之间的耦合性 , 实现了软件各层之间的解耦
??????2, 可以使用容易提供的众多服务, 如事务管理, 消息服务等
??????3, 容器提供单例模式支持
??????4, 容器提供了 AOP 技术, 利用它很容易实现如权限拦截, 运行期监控等功能
??????5, 容器提供了众多的辅助类, 能加快应用的开发
??????6,spring 对于主流的应用框架提供了集成支持, 如 hibernate,JPA,Struts 等
??????7,spring 属于低侵入式设计, 代码的污染极低
??????8, 独立于各种应用服务器
??????9,spring 的 DI 机制降低了业务对象替换的复杂性
??????10,Spring 的高度开放性, 并不强制应用完全依赖于 Spring, 开发者可以自由选择 spring 的部分或全部
十二, Spring 框架的事物管理有哪些优点
??????1, 它为不同的事物, 如 JTA,JDBC,Hibernate,JPA 和 JDO 通过了一个不变的编程模式
??????2, 它为编程式事物提供了一套简单的 API 而不是一套复杂的 API
??????3, 支持声明式事物管理
??????4, 它和 Spring 各数据访问抽象层很好的集成
十三, 列举一下你知道的实现 spring 事务的几种方式
??????1, 编程式事务管理: 需要手动编写代码, 在实际开发中很少使用
??????2, 基于 TransactionProxyFactoryBean 的声明式事务管理, 需要为每个进行事务管理的类做相应配置
??????3, 基于 AspectJ 的 xml 的声明式事务管理, 不需要改动类, 在 xml 文件中配置好即可
??????4, 基于注解的声明式事务管理, 配置简单, 需要在业务层类中添加注解
十四, 谈谈 Spring 事务的隔离级别和传播行为
?????? 隔离级别:
?????? - DEFAULT 使用数据库默认的隔离级别
?????? - READ_UNCOMMITTED 会出现脏读, 不可重复读和幻影读问题
?????? - READ_COMMITTED 会出现重复读和幻影读
?????? - REPEATABLE_READ 会出现幻影读
?????? - SERIALIZABLE 最安全, 但是代价最大, 性能影响极其严重
?????? 传播行为:
?????? - REQUIRED 存在事务就融入该事务, 不存在就创建事务
?????? - SUPPORTS 存在事务就融入事务, 不存在则不创建事务
?????? - MANDATORY 存在事务则融入该事务, 不存在, 抛异常
?????? - REQUIRES_NEW 总是创建新事务
?????? - NOT_SUPPORTED 存在事务则挂起, 一直执行非事务操作
?????? - NEVER 总是执行非事务, 如果当前存在事务则抛异常
?????? - NESTED 嵌入式事务
十五, 谈谈你对 Spring 的理解
??????1.Spring 是实现了工厂模式的工厂类(在这里有必要解释清楚什么是工厂模式), 这个类名为 BeanFactory(实际上是一个接口), 在程序中通常 BeanFactory 的子类 ApplicationContext.Spring 相当于一个大的工厂类, 在其配置文件中通过元素配置用于创建实例对象的类名和实例对象的属性.
??????2. Spring 提供了对 IoC 良好支持, IoC 是一种编程思想, 是一种架构艺术, 利用这种思想可以很好地实现模块之间的解耦, IoC 也称为 DI(Depency Injection).
??????3. Spring 提供了对 AOP 技术的良好封装, AOP 称为面向切面编程, 就是系统中有很多各不相干的类的方法, 在这些众多方法中要加入某种系统功能的代码, 例如, 加入日志, 加入权限判断, 加入异常处理, 这种应用称为 AOP.
?????? 实现 AOP 功能采用的是代理技术, 客户端程序不再调用目标, 而调用代理类, 代理类与目标类对外具有相同的方法声明, 有两种方式可以实现相同的方法声明, 一是实现相同的接口, 二是作为目标的子类.
?????? 在 JDK 中采用 Proxy 类产生动态代理的方式为某个接口生成实现类, 如果要为某个类生成子类, 则可以用 CGLIB. 在生成的代理类的方法中加入系统功能和调用目标类的相应方法, 系统功能的代理以 Advice 对象进行提供, 显然要创建出代理对象, 至少需要目标类和 Advice 类. spring 提供了这种支持, 只需要在 spring 配置文件中配置这两个元素即可实现代理和 aop 功能.
来源: http://www.bubuko.com/infodetail-3304967.html