Spring的IoC容器

Spring的IoC容器

IoC在程序开发中,实例的创建不再由调用者管理,而是由Spring容器创建。Spring容器会负责控制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了Spring容器中,控制权发生了反转,这就是Spring的IoC思想基础理论回顾

Spring是一个轻量级的控制反转IoC/DI依赖注入和面向切面AOP的开源容器框架,是一个开源的

Java/Java EE全功能栈full-stack的应用程序框架,以Apache许可证形式发布
Spring是一个轻量级的DI/IoC和AOP容器框架。存在的目的是用于构建轻量级的JavaEE应用。

Spring以一种非侵入式的方式来管理你的代码,Spring提倡”少侵入”,这也就意味着你可以适当的时候安装或卸载Spring
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能范围:任

何Java应用

简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架

Spring基础就是IoC/DI容器

简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式解决方案) 轻量级开源框架

Spring的模块化结构

6个模块20多个子项目组成的,Spring的模块化是很强的,各个功能模块都是独立的,可以选择的使用

IoC(Inversion of Control):其思想是反转资源获取的方向
DI(Dependency Injection) — 即组件以一些预先定义好的方式(例如: setter 方法)接受来自如容器的资源注入. 相对于 IoC 而言,这种表述更直接。
bean是Spring管理的基本单位,在Spring的应用中,所有的组件都是bean,bean包括数据源、
Hibernate的SessionFactory及事务管理器等。 Spring里的bean是非常广义的概念,任何的Java对象,Java组件都可被当成bean处理。甚至这些组件并不是标准的JavaBean。整个应用中各层的对
象都处于 Spring 的管理下,这些对象以 bean 的方式存在,Spring负责创建 bean 实例,并管理其生命周期。
bean在Spring容器中运行时,无须感受Spring容器的存在,一样可以接受Spring的依赖注入,包括 bean属性的注入,合作者的注入及依赖关系的注入等
Spring优势
低侵入/低耦合(降低组件之间的耦合度,实现软件各层之间的解耦。)声明式事务管理
方便集成其他框架
降低JavaEE开发难度
Spring框架中包括JavaEE 三层的每一层的解决方案 (一站式)
Spring功能
Spring能帮我们根据配置文件创建及组装对象之间的依赖关系
Spring 面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制
Spring能非常简单的帮我们管理数据库事务
Spring还提供了与第三方数据访问框架(如Hibernate、JPA)无缝集成,而且自己也提供了一套
JDBC访问模板,来方便数据库访问
Spring还提供与第三方Web(如Struts、JSF)框架无缝集成,而且自己也提供了一套Spring MVC 框架,来方便web层搭建
Spring能方便的与Java EE(如Java Mail、任务调度)整合,与更多技术整合(比如缓存框架)。
Spring的核心思想

A a = new A1()然后通过a来调用接口的方法,对于C来说是主动实例化对象,直接获取依赖。
这种实现方法的缺点:
更换实现需要重新编译源代码很难更换实现,很难测试
耦合实例生产者和实例消费者工厂模式
设计模式属于创建型模式,它提供了一种创建对象的 佳方式主要解决:主要解决接口实现的选择问题。
优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。这并不是什么好事。
工厂模式中产品可扩展,但是产品只能一种系列抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的 佳方式主要解决:提供一个创建一系列相关或相互依赖对象的接口,解决接口实现选择的问题
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
功能扩展
产品的系列不可扩展,引入资源文件,使用反射创建字串所指代的对象。
但是properties文件在IDE中缺乏语法检查,所以考虑采用xml作为配置
Spring的工厂模式实现
Spring框架 重要是提供了以类似上面xml+BeanFactory的方式管理配置在xml文件中的受管Bean
XML配置
XML可扩展标记语言,是一种依靠与SGML由w3c定义出来的标记语言。XML允许用户自定义标签,提供了2种方式说明其中的标签: dtd[ 文档类型定义]或者xsd(模式类型定义)。
Xml文件可以分为无效、良构和有效的3种,一般对xml文件的解析至少要求良构的。
XML文件作用
存储数据传递数据,即服务器以XML的形式传输数据
软件配置,即通过配置XML文件,通知应用程序如何处理业务
XML和Html的关系
XML 不是 HTML 的替代。
XML 和 HTML 为不同的目的而设计:
XML 被设计用来传输和存储数据,其焦点是数据的内容。
HTML 被设计用来显示数据,其焦点是数据的外观。
HTML 旨在显示信息,而 XML 旨在传输信息。
XML文件的解析模型
DOM
DOM是W3C处理XML的标准API,它是许多其它与XML处理相关的标准的基础,不仅是Java,其它诸如
Javascript,PHP,MS .NET 等等语言都实现了该标准, 成为了应用 为广泛的XML处理方式
形成树结构,直观好理解
解析过程中树结构保留在内存中,方便修改

当xml文件较大时,对内存消耗比较大,容易影响解析性能并造成内存溢出适用范围:小型XML文件解析、需要全解析或者大部分解析XML、需要修改XML树内容以生成自己的对象模型
SAX
SAX使用了 少的系统资源和 快速的解析方式对XML处理提供了支持。 但随之而来繁琐的查找方式也给广大程序员带来许多困扰,常常令人头痛不已
采用事件驱动模式,对内存消耗比较小适用于只需要处理xml中数据时

不易编码
很难同时访问同一个xml文件中的多处不同位置
适用范围:大型XML文件解析、只需要部分解析或者只想取得部分XML树内容、有XPath查询需求、有自己生成特定XML树对象模型的需求 Spring基本框架结构
Spring是一种JavaEE开发中的一站式解决方案,所以其中包含的内容比较多,为了避免在应用中添加无用功能,所以Spring采用了非强制性的模块化结构,在具体应用中,可以根据应用所需要的功能进行选择添加
Spring3.x分为6大模块,Spring的模块化是很强的,各个功能模块都是独立的,可以选择的使用

Core模块是Spring应用的基础,提供了 基本的IoC/DI容器的支持和实现
AOP模块建立在Core模块的基础上,提供了AOP技术的支持,以简化AOP编程的复杂度
DAO和ORM模块建立在AOP的基础上,DAO提供了dao模式编程的简化支持,ORM提供了整合持久层框架的支持。同时在AOP的基础上给数据库访问提供了声明式事务的支持
JEE模块建立在Core模块的基础上,提供了针对EJB\邮件javaMail等企业级应用支持
Web模块建立在core模块的基础上,提供了整合其它表现层框架【例如Struts\JSF等】的支持,同时提出了自己的表现层框架SpringMVC[针对Struts1提出的]

Instrumentation底层基础,是一种没有图形界面的,具有启动能力的,用于监控其他类的工具类
Test提供了单元测试的支持,要求junit4.8+版本
Spring的全方位应用程序框架

ssm=SpringMVC+Spring+MyBatis [一般开发中常用,尤其是互联网应用开发类型的公司,一般中小型快速开发中应用]
ssh[2]=Struts2+Spring+Hibernate [使用较少,一般在大型软件公司中长期使用,考试居多] 概述 IoC
IoC控制反转Inversion of control不是什么技术,而是一种设计思想。在Java开发中,IoC意味着将设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。IoC是一种让服务消费者不直接依赖于服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原则
IoC用途
IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导如何设计出松耦合、更优良的程序。传统应用程序都是在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试; 有了
IoC容器后, 把创建对象和查找依赖对象的控制权交给了容器, 由容器进行注入组合对象, 所以对象与对象之间是松散耦合, 这样也方便测试, 利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活.
其实,IoC对编程带来的 大改变不是从代码上,而是从思想上,发生了"主从换位"的变化,应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了基本概念
IoC容器
简单的理解就是,实现IoC思想,并提供对象创建、对象装配以及对象生命周期管理的软件就是IoC 容器
IoC理解
1、 应用程序无需主动new对象;而是描述对象应该如何被创建即可,IoC容器帮你创建,即被动实例化;
2、 应用程序不需要主动装配对象之间的依赖关系,而是描述需要哪个服务,IoC容器会帮你装配,被动接受装配;
3、 主动变被动,以前创建对象、装配对象的依赖关系都是由应用程序主动完成,现在变成被动了由IoC 容器来完成
4、 应用程序不知道依赖的具体实现,只知道需要提供某类服务的对象,达到并松散耦合;
5、 是一种让服务消费者不直接依赖于服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原则
使用Ioc/DI容器开发需要改变思路
1、 应用程序不主动创建对象,但是要描述创建它们的方法
2、 在应用程序代码中不直接进行服务的装配,但是要描述哪一个组件需要哪一项服务,由容器负责将这些装配在一起
也就是说:所有的组件都是被动的,组件初始化和装配都由容器负责,应用程序只是获取相应的组件后,实现应用的功能即可概述 DI
DI依赖注入Dependency Injection即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中. 依赖注入的目标并非为软件系统带来更多的功能,而是为了提升组件重用的概率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不用关心具体的资源来自何处、由谁实现
控制反转和依赖注入
它们不是同一个概念,但是它们是同一个概念的不同角度的描述
控制反转IoC从 IoC容器的角度来说依赖注入DI从应用程序的角度来说
IoC/DI的基本思想
1、 把程序之间的依赖关系去掉
2、 把程序对象设置到IoC/DI容器的配置中,作为Bean来统一管理
3、 由IoC/DI容器来管理Bean的创建、实例化
4、 由IoC/DI容器来把Bean之间的关系注入到需要这些关系的对象里面
简而言之:就是把对象之间的依赖关系全部去掉,由IoC/DI容器来管理对象和对象之间的依赖关系,实现对象之间的松散耦合
使用IoC/DI容器开发需要改变思路
1、应用程序不主动创建对象,但是要描述创建它们的方法 2、在应用程序代码中不直接进行服务的装配,但是要描述哪一个组件需要哪一项服务,由容器负责将这些装配在一起 也就是说:所有的组件都是被动的,组件初始化和装配都由容器负责,应用程序只是获取相应的组件后,实现应用的功能即可受管bean的定义方法
配置方式有3种: XML、xml+Annoration、JavaConfig
Bean的创建方式:通过全类名(反射)、通过工厂方法(静态工厂方法 & 实例工厂方法)、
FactoryBean
受管bean的配置方式
定义对应的类,并进行配置,将对象纳入到容器中进行管理(受管bean)
【(Spring2.5-)xml配置 xml+注解配置 (Spring4.0+建议)JavaConfig类配置】
xml配置:适合实现类来源于第三方类库,可以引入对应的命名空间简化配置
注解配置:适合实现类是当前项目开发的,可以直接在Java类中使用基于注解的配置
JavaConfig类配置:优势在于可以通过代码方式控制bean初始化的整体逻辑
Spring的核心配置文件applicationContext.xml
1
2 3 xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
4 xmlns:p=“http://www.springframework.org/schema/p”
5 xsi:schemaLocation=“http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd”>
6 7

XML受管bean

< bean id=“名称” name="" class="" scope=""/>
没有任何特殊要求,一般Java类都可以充当JavaBean,一般需要无参构造器,private属性和public的 get/set方法, 非final类

id为在代码中引用的名称,唯一,且可以为多个,利用逗号、分号、或空格分隔 class指向全类名,spring就是根据全类名,通过反射生成一个实例对象,id为这个实例对象的引用,所以必须在这个类中添加默认的构造方法,并且属性要有setter方法
scope
singleton单例,是默认属性:Spring将Bean放入Spring IoC容器的缓存池中,并将Bean引用返回给调用者,spring IoC容器负责对这些Bean进行后续的生命管理。BeanFactory只管理一个共享的实例。所有对这个特定bean的实例请求,都导致返回这个唯一bean实例的引用。即每次拿到的对象都是引用的同一个地址的对象。当一个bean被标识为singleton时候,spring 的IoC容器中只会存在一个该bean
prototype原型:不管是BeanFactory或者ApplicationContext都是延迟加载使用的。每次对这个bean的实例请求都会导致一个新的实例的创建。当用户需要不受其他用户对象影响的对象或有类似的需求时,这是一个较理想的解决办法。即每次拿到的对象都是引用的不同地址的
对象。相当于一个new的操作。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责
以下3种scope都使用的较少,有request\session\global session,类似于JavaEE里面的 request和session。在使用SpringMVC是可能会用到 request表示针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP
request内有效
session表示一个用户【客户】对应一个新的bean
global session作用域类似于标准的HTTPSession作用域,不过仅仅在基于portlet的web
应用中才有意义
注意:对于struts2中的Action来说需要指明scope=prototype,因为struts2的Action要求是多实例、单线程的

建议:private属性public的get/set方法、 无参构造器、 非fianl类

所谓依赖注入,是指程序运行过程中,如果需要调用另一个对象协助时,无须在代码中创建被调用
者,而是依赖于外部的注入 xml+Annoration
一类是使用Bean,即是把已经在xml文件中配置好的Bean拿来用,完成属性、方法的组装;比如
@Autowired , @Resource,可以通过byTYPE(@Autowired)、byNAME(@Resource)的方式获取
Bean
一类是注册Bean,@Component , @Repository , @ Controller , @Service , @Configration这些注解都是把你要实例化的对象转化成一个Bean,放在IoC容器中,等要用的时候,它会和上面的@Autowired ,
@Resource配合到一起,把对象、属性、方法完美组装

相关注解
1、 @Service用于标注业务层组件
2、 @Controller用于标注控制层组件(如struts2中的action)
3、 @Repository用于标注数据访问组件,即DAO组件.
4、 @Component泛指组件,当组件不好归类的时候,可以使用这个注解进行标注
可以添加参数value="名称"或者直接定义字串类型名称。如果不定义名称,则默认受管bean的名称为类名称,首字母小写.
@Scope(“prototype”)来改变范围设置,不设置则默认为singleton

定义受管bean的方法
@Component 这里用于声明这个类是受管bean,默认名称为类名称,首字母小写。如果需要可以添加属性配置(value=”名称”)人为设置受管bean的id名称,注意这里的value=可以省略

注入被依赖对象
@Resource

JavaConfig

Bean的创建方式
配置Bean其实就是使用DI依赖注入将Bean交给IoC容器管理,实现IoC控制反转达到解耦的过程通过全类名反射创建

通过工厂方法创建
一般用于整合旧有系统或者Spring整合其它框架时静态工厂

实例工厂方法

先创建DaoFactrory对象userDaoFactory,然后获取userDao对象时,是通过调用userDaoFactory对象的getUserDao方法获取

BeanFactory和ApplicationContext
Spring 提供了两种类型的IoC容器实现
BeanFactory是IoC 容器的基本实现,ApplicationContext 提供了更多的高级特性,是 BeanFactory的子接口针对单例类型的受管bean,BeanFactory默认采用延迟加载,ApplicationContext默认采用立即加载
BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;ApplicationContext 面向使用
Spring 框架的开发者,几乎所有的应用场合都直接使用 ApplicationContext 而非底层的
BeanFactory

获取IoC容器的引用(不使用测试框架)
1 Resource r = new ClassPathResource(“applicationContext.xml”);
2 //ClassPathResource表示从classpath中查找对应的核心配置文件[名称允许修改,但是一般不建议]applicationContext.xml,另外还有一个实现类为
FileSystemResource(“c:\beans.xml”)表示使用绝对路径查找对应的核心配置文件
3
4 BeanFactory fac = new XmlBeanFactory®;获取到IoC容器的引用,XmlBeanFactory表示配置文件是xml文件,注意另外其他配置方法,不建议使用
5
6 Date now = (Date) fac.getBean(“now”);通过受管bean的名称在容器中查找对应由容器创建的受管bean对象
7 System.out.println(now);
import org.springframework.beans.factory.xml.XmlBeanFactory;IDE工具已经提示BeanFactory不是建议使用的,建议使用ApplicationContext接口 ApplicationContext接口的用法:

ApplicationContext接口继承于BeanFactory接口,主要用于引用IoC/DI容器,ApplicationContext具有
BeanFactory的所有功能,另外提供针对企业级开发的功能支持
BeanFactory接口
BeanFactory定义了 IoC 容器的 基本形式,并提供了 IOC 容器应遵守的的 基本的接口重点方法:
getBean(Class):T在IoC容器中按照类型查找所有的受管bean对象
如果一个类型有2个受管配置,则按类型查找出错NoUniqueBeanDefinitionException
getBean(“名称”):Object 按照受管bean的名称获取受管bean的对象
T getBean(String受管bean名称, Class目标类型) : 返回以给定名称注册的Bean,返回的
Bean将被cast给定的类。如Bean不能被Cast,异常BeanNotOfRequiredTypeException将被抛出

不重要的方法
boolean containsBean(String受管bean的名称): 如果BeanFactory包含符合给定名称的Bean定义或Bean实例,则返回true
Class getType(String name受管bean的名称): 返回给定名称的Bean的 Class。如果对应的Bean找不到,则会抛出NoSuchBeanDefinitionException异常 boolean isSingleton(String): 决定在给定名称时,Bean定义或Bean实例注册是否为单例模式,如果对应的Bean不能被找到,则抛出异常
String[] getAliases(String): 如果在Bean的定义中有定义,则返回给定Bean名称的别名

BeanFacotry是spring中比较原始的Factory,提供了IoC/DI容器使用的 基本的方法。
ApplicationContext接口由BeanFactory接口派生而来,在提供BeanFactory所有的功能基础上提供了企业级应用开发的支持,例如读取资源文件、发布事件等。
BeanFactory针对单例的受管bean采用的是延迟加载,ApplicationContext采用的是立即加载【所有的 prototype受管bean都是延迟】。所以BeanFactory一般用于内存敏感的受限环境开发中,
ApplicationContext一般使用
工厂模式和IoC的特点和区别
主要区别体现在调用的代码,如果使用IoC,在代码中将不需要嵌入任何工厂模式等的代码,因为这些工厂模式其实还是与被调用者有些间接的联系,这样使用IoC彻底解耦了工厂和被调用之间的联系
使用IoC带来的代价是:需要在客户端或其它某处进行工厂和被调用之间联系的组装。所以IoC并没有消除工厂和被调用之间这样的联系,只是转移了这种联系这种联系转移实际也是一种分离关注,它的影响巨大,它提供了AOP实现的可能

设计中要求: 上层类不依赖于下层的具体实现,而是依赖于下层的接口,允许下层的实现进行任意切换上层类
1 public class UserServImpl implements IUserServ {
2 private IUserDao userDao;//上层类只和下层接口耦合,并不耦合具体的
3 public void abc() {
4 System.out.println(“userServImpl begin…”);
5 userDao.pp();
6 System.out.println(“userServImpl end…”); }
7 public IUserDao getUserDao() {return userDao; }
8 public void setUserDao(IUserDao userDao) {this.userDao = userDao; }
9 } 底层接口

配置方法1:
1
2
3
4
5
6
配置方法2:引入p名空间
拷贝基础名空间,xmlns=“http://www.springframework.org/schema/beans” 修改为xmlns:p=“http://www.springframework.org/schema/p”
1 由容器负责创建 userDao对象
2 3 p:userDao-ref=“userDao” />由容器负责创建userServcice对象,并且将userDao对象通过userService的set方法注入到IUserDao userDao属性上
依赖注入
所谓依赖注入,是指程序运行过程中,如果需要调用另一个对象协助时,无须在代码中创建被调用者,
而是依赖于外部的注入 依赖注入通常有三种方法:接口注入、设置注入和构造器注入[Spring工厂注入]
接口注入
接口注入方式发展的比较早,在实际中也得到了普遍的应用。在编程时,常常借助接口来将调用者与实现者相分离。对于一个接口注入型IoC容器而言,加载接口实现并创建其实例的工作由容器完成,J2EE开
发中常用的Context.lookup()都是接口注入型IoC的表现形式
Servlet中的doGet()和doPost()方法是接口注入,HttpServletRequest和HttpServletResponse实例由 Servlet Container在运行期动态注入
由于其在灵活性、易用性上不如其他两种注入模式,因而在IoC的专题世界内并不被看好
设置器注入:属性注入
要求无参构造器和对应的set方法
属性注入即通过 setter 方法注入Bean 的属性值或依赖的对象,使用property元素, 使用 name 属性指定 Bean 类的属性名称,value 属性或子节点指定属性值。【在这里,注入是根据setter方法来的而不是属性名称,但是一般我们都是直接生成setter方法,而不去更改这个名称,所以就是说成name为属性名称】
这种注入方式简单、直观,因而在Spring的依赖注入中大量使用。如果依赖关系较为复杂,那么构造器
注入模式的构造函数也会相当庞大,此时设置器注入模式往往更为简洁

没有-ref用于针对简单类型的属性: 8种简单类型及其包装类或者字串类型

特殊设置

对于某些第三方类库而言,可能要求组件必须提供一个默认的构造函数(如Struts中的Action),此时构造器注入类型的依赖注入机制就体现出其局限性,难以完成期望的功能。
构造方法注入
通过构造方法注入Bean 的属性值或依赖的对象,它保证了 Bean 实例在实例化后就可以使用。 构造器注入在 【constructor-arg】 元素里声明属性

配置Bean其实就是使用DI依赖注入,将Bean交给IOC容器管理,实现IOC控制反转,达到解耦的过程

对应的构造器可以是private,Spring采用的是反射的方法;但是注意set方法不能是非public的,否则设置器注入失效

在构造期即创建一个完整、合法的对象,对于这条Java设计原则,Type3无疑是 好的响应者
避免了繁琐的setter方法的编写,所有依赖关系均在构造函数中设定,依赖关系集中呈现,更加易读
由于没有setter方法,依赖关系在构造时由容器一次性设定,因此组件在被创建之后即处于相对“不变”的稳定状态
同样由于关联关系仅在构造函数中表达,组件中的依赖关系处于黑盒之中。对上层屏蔽不必要的信息通过构造子注入,意味着可以在构造函数中决定依赖关系的注入顺序设置器注入和构造器注入的选择
设置器注入和构造器模式各有千秋,而Spring对构造器注入和设置器注入类型的依赖注入机制提供了良好支持。
理论上,以构造器注入类型为主,辅之以设置器注入类型机制作为补充,可以达到最好的依赖注入效果。
一般来说,对于基于Spring Framework开发的应用而言,设置器注入使用更加广泛强调:不要滥用依赖注入
ApplicationContext可以创建Java对象,但并不是所有的Java对象都通过依赖注入来创建的
Spring是一个很棒的框架,但是就易读性和易管理性而言,当定义大量bean的时候,基于XML的配置问题就会突出。过度依赖注入会使XML配置变得复杂而且臃肿
定义大量bean的时候,使用强大的IDE时,例如Eclipse,与XML文件相比,Java代码更加易读,易维护,易管理
控制反转和依赖注入
IoC实现由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控,控制权由应用代码中转到了外部容器,控制权的转移,是所谓控制反转。实际上真正的IoC有两种实现方式DI和DL
可供选择的IoC 容器: Apache Avalon、PicoContainer 和 HiveMind。Avalon 从没怎么流行,尽管它很强大而且有很长的历史。Avalon相当的重和复杂,并且看起来比新的IoC解决方案更具侵入性。PicoContainer是一个轻量级而且更强调通过构造函数表达依赖性而不是JavaBean 属性。 与 Spring不同,它的设计允许每个类型一个对象的定义(可能是因为它拒绝任何Java代码外的元数据导致的局限性)
Martin Fowler给IoC起更为直观的名字:Dependency Injection依赖注射DI。创建被调用者实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入
针对Person属性birth由容器负责调用Person对象的setBirth将now对象设置进去
IoC和DI的区别
IoC—Inversion of Control 控制反转意味着将设计好的对象交给容器控制,而不是传统的在你对象内部直接控制。IoC容器来控制对象的创建,主要控制了外部资源获取(不仅仅是对象,也包括文件);由容器查找及注入以来对象,对象只说被动接受依赖对象,所以反转;依赖对象的获取反转了
DI—Dependency Injection依赖注入:是组件之间依赖关系由容器在运行期决定。通俗的说,由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。应用程序依赖于IoC容器;IoC容器注入应用程序某个对象,应用程序依赖的对象;注入某个对象所需要的外部资源(对象、资源、常亮数据)
Spring和EJB的比较
相对于EJB来说,Spring是一个轻量级的JavaEE应用开发框架,使把各个技术层次之间的风险降低。EJB 就是企业级JavaBean。EJB2是重量级,运行必须有对应的容器。EJB3使用JPA已经偏向于轻量级
EJB的内聚性较强,内聚性的白盒特征使我们必须放弃一部分可控性而去信任容器能力。而Spring则是考虑如何“不造轮子”,如何更好的组装这些轮子,让他们更好的转动
IoC/DI模式的优点
颠覆了“使用对象之前必须创建” 的基本Java语言定律 ,降低了模块之间的耦合度,提高了应用的灵活性和代码重用度。
使用IoC模式,完全在一个抽象层次进行描述和技术架构,因此,IoC模式可以为容器、框架之类的软件实现提供了具体的实现手段
Bean的生命周期
init-method=”方法名称” 老方法是实现一个接口Spring的InitializingBean为bean提供了定义初始化方法的方式。InitializingBean是一个接口,它仅仅包含一个方法:afterPropertiesSet()。这个方法在对象创建完毕(构造器),然后执行setXXX方法后自动执行,目前建议采用init-method配置即可,不用实现接口,主要可以定义一些初始化动作,这个方法在整个对象的生命周期中运行且只运行一次.方法签名中可以返回任意类型,允许抛出异常,但是不能包含参数
Spring要求init-method是一个无参数的方法,如果init-method指定的方法中有参数,那么Spring将会抛出java.lang.NoSuchMethodException
init-method指定的方法可以是public、protected以及private的,并且方法也可以是final的。
init-method指定的方法可以是声明为抛出异常的
如果在init-method方法中抛出了异常,那么Spring将中止这个Bean的后续处理,并且抛出一个 org.springframework.beans.factory.BeanCreationException异常。

destroy-method配置对应DisposableBean接口,可以定义一个在对象销毁之前执行的方法,可以用于进行资源的释放… 这个方法在整个对象的生命周期中运行且只运行一次.方法规则同init-method配置

@Lazy注解用于描述类,其目的是告诉spring框架此类支持延迟加载
@PostConstruct注解用于描述bean对象生命周期方法中的初始化方法,此方法会在对象的构造方法之后执行
@PreDestroy注解用于描述Bean对象生命周期方法中的销毁方法,此方法会在对象销毁之前执行集合对象属性注入直接配置的方法

在spring的配置文件中util命名空间类似于java.util包类对应,util命名空间提供了集合相关的配置,在使用命名空间前要导入util命名空间
1 3 xsi:schemaLocation=“http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd”> 配置一个List

配置一个Map集合

配置一个Set集合

配置一个Properties集合

读取properties文件

自动装配autowire协作者

Spring IoC容器可以自动装配autowire相互协作bean之间的关联关系。因此,如果可能的话,可以自动让Spring通过检查BeanFactory中的内容,来替我们指定bean的协作者(其他被依赖的bean)。

优点
1、 自动装配能显著减少配置的数量。不过,采用bean模板(见这里)也可以达到同样的目的。
1
2
3
4
5
6
2、 自动装配可以使配置与java代码同步更新。例如,如果你需要给一个java类增加一个依赖,那么该依赖将被自动实现而不需要修改配置。因此强烈推荐在开发过程中采用自动装配,而在系统趋于稳定的时候改为显式装配的方式
自动装配有几种类型
5种模式
1、 no 是默认值,表示不使用autowiring。 必须显示的使用标签明确地指定bean合作者,对于部署给予更大的控制和明了。
2、 byName 根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配。例如,在bean定义中将 autowire设置为by name,而该bean包含master属性(同时提供setMaster(…)方法),Spring就会查找名为master的bean定义,并用它来装配给master属性。
3、 byType 如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配。如果存在多个该类型的bean,那么将会抛出异常,并指出不能使用byType方式进行自动装配。若没有找到相匹配的 bean,则什么事都不发生,属性也不会被设置。如果不希望这样,那么可以通过设置 dependencycheck=“objects"让Spring抛出异常。
4、 constructor 与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。 5、default采用默认自动装配方法
autodetect – 如果找到默认的构造函数,使用自动装配用构造;否则,使用按类型自动装配。【在 Spring3.0以后的版本被废弃,已经不再合法了】自动装配的配置方法
1 设置默认的自动装配方法,no表示不采用自动
2
3
4
5
自动装配的一些缺点
1、 尽管自动装配比显式装配更神奇,但是,正如上面所提到的,Spring会尽量避免在装配不明确的时候进行猜测,因为装配不明确可能出现难以预料的结果,而且Spring所管理的对象之间的关联关系也不再能清晰的进行文档化。
2、 对于那些根据Spring配置文件生成文档的工具来说,自动装配将会使这些工具没法生成依赖信息。
3、 自动装配可以减轻配置的工作量,但同时使得配置文件的可读性变得很差,因为你不可能从配置文件中获知这些对象之间得依赖关系,从而维护困难!
注意: 当根据类型进行自动装配的时候,容器中可能存在多个bean定义跟自动装配的setter方法和构造器参数类型匹配。这样就会存在模棱两可的问题。如果bean定义不唯一,装配时就会抛出异常。
解决方案(任选其一):
1 放弃使用自动装配,使用显示装配。
2 将bean排除在自动装配之外两个功能:
1 通过设定bean定义中的’autowire-candidate’属性显式的设置为’true’ 或 ‘false’来设置其是否为被自动装配对象。
2 使用对bean名字进行模式匹配来对自动装配进行限制,其做法是在元素的’default-
autowire-candidates’ 属性中进行设置。可以使用通配符,如以’Repository’结尾的bean,那么可以设置为”*Repository“。
3 通过在bean定义中设置’primary’属性为’true’来将该bean设置为首选自动装配bean。
自动装配的检查 dependency-check
取值 说明
default 不查
simple 只查原始类型是否装配
objects 只查引用类型是否装配
all 全部查看
lazy-init=true告诉IoC容器在第一次被用到时实例化。applicationContext默认在启动时将所有的
Singleton Bean提前初始化
depends-on属性用于当前bean初始化之前显式地强制一个或多个bean被初始化。依赖是将一个bean 设置为另外一个bean的属性,在xml配置文件中使用元素特殊用法

继承Bean的配置方式
Spring允许继承bean的配置, 被继承的bean称为父bean. 继承这个父Bean的Bean称为子Bean
子 Bean 从父 Bean 中继承配置, 包括 Bean 的属性配置子 Bean 也可以覆盖从父 Bean 继承过来的配置
父 Bean 可以作为配置模板, 也可以作为 Bean 实例. 若只想把父 Bean 作为模板, 可以设置
的abstract 属性为 true, 这样 Spring 将不会实例化这个 Bean 并不是 元素里的所有属性都会被继承. 比如: autowire, abstract 等 也可以忽略父 Bean 的 class 属性, 让子 Bean 指定自己的类, 而共享相同的属性配置. 但此时 abstract 必须设为 true

依赖bean
Spring允许用户通过depends-on属性设定 Bean前置依赖的Bean,前置依赖的Bean会在本Bean 实例化之前创建好
如果前置依赖于多个 Bean,则可以通过逗号,空格或的方式配置 Bean 的名称
默认情况下按照配置的顺序构建受管bean对象

执行顺序为B.B()====A.A()====B.setA() 使用外部属性文件
在配置文件里配置Bean时, 有时需要在Bean的配置里混入系统部署的细节信息(如文件路径, 数据源配置信息等). 而这些部署细节实际上需要和 Bean 配置相分离
Spring提供了PropertyPlaceholderConfigurer的BeanFactory后置处理器, 这个处理器允许用户将Bean 配置的部分内容外移到属性文件中. 可以在Bean配置文件里使用形式为 v a r 的 变 量 , P r o p e r t y P l a c e h o l d e r C o n f i g u r e r 从 属 性 文 件 里 加 载 属 性 , 并 使 用 这 些 属 性 来 替 换 变 量 . S p r i n g 还 允 许 在 属 性 文 件 中 使 用 {var}的变量, PropertyPlaceholderConfigurer从属性文件里加载属性, 并使用这些属性来替换变量. Spring还允许在属性文件中使用 var,PropertyPlaceholderConfigurer,使.Spring使{propName}以实现属性之间的相互引用

在src目录下创建properties文件,这里包含数据库连接的相关配置信息

使用context名空间可以实现读取并解析特定的资源文件,并在其它配置的地方通过SpEL【Spring表达式语言】进行调用,以简化配置信息
1 用于读取并解析properties文件
2 3 p:driverClass=" j d b c . d r i v e r " p : j d b c U r l = " {jdbc.driver}" p:jdbcUrl=" jdbc.driver"p:jdbcUrl="{jdbc.url}" p:user=" j d b c . u s e r n a m e " 4 p : p a s s w o r d = " {jdbc.username}" 4 p:password=" jdbc.username"4p:password="{jdbc.password}" destroy-method=“close” />在xml配置中只管理连接,不包含数据库相关配置信息,这里的 是 S p E L [ s p r i n g − e x p r e s s i o n ] , 这 是 S p r i n g 的 表 达 式 语 言 , 用 于 简 化 配 置 文 件 , {}是SpEL[spring-expression],这是Spring的表达式语言,用于简化配置文件, SpEL[springexpression],Spring{jdbc.username}表示从上面解析出properties中获取键值为 jdbc.username所对应的值.一般针对数据源建议配置destroy-method表示在销毁连接池之前,释放连接池中的所有连接
5
Spring中引入其他配置文件

SpEL的使用
Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。语法类似于 EL:SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL SpEL 为 bean 的属性进行动态赋值提供了便利通过 SpEL 可以实现:
通过 bean 的 id 对 bean 进行引用调用方法以及引用对象中的属性计算表达式的值正则表达式的匹配
字面量的表示
整数: 小数: 科学计数法:
String可以使用单引号或者双引号作为字符串的定界符号: 或
Boolean:

注解的使用
如果把Bean都在Spring的配置文件中进行配置,那么随着项目的进展,配置文件的体积会急速的增加,加重开发人员对配置文件维护的的负担
在Spring3中,Spring容器提供了利用Annotation注解的方法自动扫描ClassPath中Bean的功能,利用这个功能,可以极大的减轻配置文件的体积注解分为两类
1、 一类是使用Bean,即是把已经在xml文件中配置好的Bean拿来用,完成属性、方法的组装;比如
@Autowired , @Resource,可以通过byTYPE(@Autowired)、byNAME(@Resource)的方式获取
Bean;
2、 一类是注册Bean,@Component , @Repository , @ Controller , @Service , @Configration这些注解都是把你要实例化的对象转化成一个Bean,放在IoC容器中,等你要用的时候,它会和上面的 @Autowired , @Resource配合到一起,把对象、属性、方法完美组装。

组件扫描(component scanning): Spring 能够从 classpath 下自动扫描, 侦测和实例化具有特定注解的组件.
特定组件包括:
@Component: 基本注解, 标识了一个受 Spring 管理的组件
@Respository: 标识持久层组件
@Service: 标识服务层(业务层)组件
@Controller: 标识表现层组件
对于扫描到的组件, Spring 有默认的命名策略: 使用非限定类名, 第一个字母小写. 也可以在注解中通过 value 属性值标识组件的名称

当在组件类上使用了特定的注解之后, 还需要在 Spring 的配置文件中声明 scan>
base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类当需要扫描多个包时, 可以使用逗号分隔
如果仅希望扫描特定的类而非基包下的所有类,可使用 resource-pattern 属性过滤特定的类,示
例:
context:include-filter 子节点表示要包含的目标类
context:exclude-filter 子节点表示要排除在外的目标类
context:component-scan下可以拥有若干个 context:include-filter 和
context:exclude-filter 子节点

@Autowired 注解自动装配具有兼容类型的单个 Bean属性构造器, 普通字段(即使是非 public), 一切具有参数的方法都可以应用@Authwired 注解
默认情况下, 所有使用 @Authwired 注解的属性都需要被设置. 当 Spring 找不到匹配的 Bean 装配属性时, 会抛出异常, 若某一属性允许不被设置, 可以设置 @Authwired 注解的 required 属性为 false
默认情况下, 当 IOC 容器里存在多个类型兼容的 Bean 时, 通过类型的自动装配将无法工作. 此时可以在
@Qualifier 注解里提供 Bean 的名称. Spring 允许对方法的入参标注 @Qualifiter 已指定注入 Bean 的名称
@Authwired 注解也可以应用在数组类型的属性上, 此时 Spring 将会把所有匹配的 Bean 进行自动装配.
@Authwired 注解也可以应用在集合属性上, 此时 Spring 读取该集合的类型信息, 然后自动装配所有与之兼容的 Bean.
@Authwired 注解用在 java.util.Map 上时, 若该 Map 的键值为 String, 那么 Spring 将自动装配与之 Map 值类型兼容的 Bean, 此时 Bean 的名称作为键值

Spring 还支持 @Resource 和 @Inject 注解,这两个注解和 @Autowired 注解的功用类似
@Resource 注解要求提供一个 Bean 名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为 Bean 的名称
@Inject 和 @Autowired 注解一样也是按类型匹配注入的 Bean, 但没有 reqired 属性。建议使用
@Autowired 注解
1、 @Inject是JSR330 (Dependency Injection for Java)中的规范,需要导入javax.inject.Inject;实现注入。
2、 @Inject是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Named;
3、 @Inject可以作用在变量、setter方法、构造函数上。
@Named(“XXX”)中的 XX是 Bean 的名称,所以 @Inject和@Named结合使用时,自动注入的策略就从 byType转变成 byName 了。

总结
1、 @Autowired是spring自带的,@Inject是JSR330规范实现的,@Resource是JSR250规范实现的,需要导入不同的包
2、 @Autowired、@Inject用法基本一样,不同的是@Autowired有一个request属性
3、 @Autowired、@Inject是默认按照类型匹配的,@Resource是按照名称匹配的
4、 @Autowired如果需要按照名称匹配需要和@Qualifier一起使用,@Inject和@Name一起使用

注解配置相对于XML配置优势
可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作
注解和 Java 代码位于一个文件中,而 XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和Java代码放在一起,有助于增强程序的内聚性。而采用独立的XML配置文件,在编写一个功能时,往往需要在程序文件和配置文件中不停切换,这种思维上的不连贯会降低开发效率
在很多情况下,注释配置比 XML 配置更受欢迎,注释配置有进一步流行的趋势。spring 2.5 的一大增强就是引入了很多注释类,现在已经可以使用注释配置完成大部分 XML 配置的功能注解配置和XML配置的适用场合
注解配置不一定在先天上优于XML配置。如果Bean的依赖关系是固定的,这种配置信息不会在部署时发生调整,那么注解配置优于XML配置;反之如果这种依赖关系会在部署时发生调整,XML配置又优于注解配置,因为注解是对 Java 源代码的调整,需要重新改写源代码并重新编译才可以实施调整如果Bean不是自己编写的类注解配置将无法实施,此时 XML 配置是唯一可用的方式
注解配置往往是类级别的,而XML配置则更加灵活。所以在实现应用中往往需要同时使用注解配置和
XML配置,对于类级别且不会发生变动的配置可以优先考虑注解配置;而对于那些第三方类以及容易发生调整的配置则应优先考虑使用XML配置。Spring会在具体实施Bean创建和Bean注入之前将这两种配置方式的元信息融合在一起。
整合多个配置文件
Spring允许通过将多个配置文件引入到一个文件中,进行配置文件的集成。这样在启动
Spring容器时,仅需要指定这个合并好的配置文件就可以。
import元素的resource属性支持Spring的标准的路径资源

Spring 4.x 新特性:泛型依赖注入可以为子类注入子类对应的泛型类型的成员变量的引用

字面值:可用字符串表示的值,可以通过元素标签或value属性进行注入。
基本数据类型及其封装类、String等类型都可以采取字面值注入的方式。若字面值中包含特殊字 符,可以使用 把字面值包裹起来。
面试题

什么是Spring IoC 容器。 控制反转即IoC ,它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现组件对象的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。Spring IOC 负责创建对象,管理对象,装配对象,配置对象,并且管理这些对象的整个生命周期。

控制反转(IoC)有什么作用
管理对象的创建和依赖关系的维护方便解耦,由容器去维护具体的对象托管了类的产生过程。

控制反转(IoC)的优点是什么?
把应用的代码量降到 低
它使应用容易测试,单元测试不再需要单例和JNDI查找机制
小的代价和 小的侵入性使松散耦合得以实现
IoC容器支持加载服务时的饿汉式初始化和懒加载。

Spring IoC 的实现机制 Spring 中的 IoC 的实现原理就是工厂模式加反射机制。

Spring 的 IoC支持哪些功能 依赖注入、依赖检查、自动装配、支持集合、指定初始化方法和销毁方法、支持回调某些方法

ApplicationContext 通常的实现是什么?
FileSystemXmlApplicationContext容器 :此容器从一个XML 文件中加载 beans 的定义,XML
Bean配置文件的全路径名必须提供给它的构造函数
ClassPathXmlApplicationContext容器:此容器从一个 XML 文件中加载 beans 的定义,需要正确设置 classpath 。因为这个容器将在 classpath 里面找 bean 的配置
WebXmlApplicationContext容器:此容器加载一个 XML 文件,此文件定义了一个 WEB 应用的所有 bean。

BeanFactory和 Application contexts 有什么区别?
BeanFactory:是Spring里面 低层的接口,提供了 简单的容器的功能,而且只提供了实例化对象和拿对象的功能;
ApplicationContext:是应用上下文,继承BeanFactory接口,它是Spring的一个更高级的容器,提供了更多的有用的功能,这些功能包括;国际化访问资源,如URL和文件载入多个有继承关系的
上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层 消息发送和响应机制
AOP
两者的区别在于装载beans时的区别:BeanFactory在启动的时候不会去实例化Bean,当Spring应用中有从容器拿Bean的时候才会去实例化;ApplicationContext在启动的时候就把所有的Bean全部实例化了,它还可以通过配置来实现Bean的延迟实例化,所以实际开发中推荐使用Application contexts。

一个 Spring 的应用看起来像什么?
一个定义了一些功能的接口
Spring AOP
Spring 的 XML 配置文件使用以上功能的客户端程序

什么是Spring的依赖注入(DI)?
依赖注入是组件之间的依赖关系,由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例化,并注入到应用系统中的各个关联的组件之中。组件不做定位查询,只提供普通的
Java方法让容器去决定依赖关系。

依赖注入的基本原则? 应用组件不应该负责查找资源或者其他依赖的协作对象。 配置对象的工作应该由
IoC容器负责,查找资源的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责。 IoC容器全权负责组件的装配,它会把符合依赖关系的对象通过属性或者是构造器传递给需要的对象。

依赖注入有什么优势 查找定位操作与应用代码完全无关。 不依赖于容器的API,可以很容易地在任何容器以外使用应用对象。 不需要特殊的接口,绝大多数对象可以做到完全不必依赖容器。

有哪些不同类型的依赖注入方式,推荐使用哪种? 构造器注入、接口注入和 Setter 方法注入。 好的解决方案是用构造器参数实现强制依赖, setter 方法实现可选依赖。

什么是 Spring Beans ?
Spring beans 是那些形成 Spring 应用主干的 java 对象,它们被 Spring IOC 容器初始化,装配,和管理,这些 beans 通过容器中配置的元数据创建。

一个 Spring Bean 定义包含什么?
一个 Spring Bean 的定义包含容器必知的所有配置元数据,包括如何创建一个bean,它的生命周期详情及它的依赖。

如何给 Spring 容器提供配置元数据?
XML 配置文件
基于注解的配置
基于 java 的配置。

你怎样定义类的作用域?
当在 Spring 里定义一个 ,可以给这个 bean 声明一个作用域,还可以通过 bean 定义中的 scope 属性来定义作用域。如,当 Spring 在需要的时候每次生产一个新的 bean 实例,bean 的 scope 属性被指定为 prototype。另一方面,一个 bean 每次使用的时候必须返回同一个实例,这个 bean 的 scope 属性必须设为singleton

解释 Spring 支持的几种bean的作用域?
singleton作用域 : 是spring默认的作用域,bean 在每个 Spring ioc 容器中只有一个实例
prototype作用域:一个 bean 的定义可以有多个实例,但该作用域谨慎使用,频繁创建和销毁会严重影响性能
request作用域:每次 http 请求都会创建一个 bean, 该作用域仅在基于 web 的 Spring Application Context 情况下有效
session作用域:在一个 HTTP Session 中,一个 bean 定义对应一个实例。该作用域仅在基于 web 的 Spring Application Context 情况下有效
global-session作用域:在一个全局的 HTTP Session 中,一个 bean 定义对应一个实例。该作用域仅在基于 web 的 Spring Application Context 情况下有效。

Spring 框架中的单例 bean是线程安全的吗?
Spring 框架中的单例 bean 不是线程安全的,spring 中的 bean 默认是单例模式,Spring框架并没有对单例 bean 进行多线程的封装处理。实际上大部分时候 spring bean 是无状态的(比如 dao类),某种程度上来说 bean 也是安全的,但如果 bean 有状态的话(比如 view model 对象),那就要开发者自己去保证线程安全了。 简单的就是改变 bean 的作用域,把“singleton”变更为“prototype”,这样请求 bean 相当于 new Bean()了,就可以保证线程安全了

解释 Spring 框架中 bean 的生命周期
Spring 容器从XML 文件中读取 bean 的定义,并实例化 bean。Spring 根据 bean 的定义填充所有的属性。
如果 bean 实现了 BeanNameAware 接口.Spring 传递 bean 的ID到 setBeanName 方法。
如果 Bean 实现了 BeanFactoryAware 接口, Spring 传递 beanFactory 给 setBeanFactory 方法。
如果有任何与 bean 相关联的 BeanPostProcessors, Spring 会在 postProcesserBeforeInitialization() 方法内调用它们.
如果 bean 实现 IntializingBean 了,调用它的 afterPropertySet 方法,如果 bean 声明了初始化方法,调用此初始化方法。
如果有 BeanPostProcessors 和 bean 关联,这些 bean 的 postProcessAfterInitialization() 方法将被调用。
如果 bean 实现了 DisposableBean 它将调用 destroy() 方法。

哪些是重要的 bean 生命周期方法?你能重载它们吗?
有两个重要的 bean生命周期方法,第一个方法是 setup,它是在容器加载 bean 的时候被调用。第二个方法是teardown ,它是在容器卸载类的时候被调用。Bean 标签有两个重要的属性(init-method和 destroy-method),可以通过这两个属性定制初始化和注销方法,它们也有相应的注解
(@PostConstruct和@PreDestroy )。

什么是 Spring 的内部 bean(什么是Spring inner beans)?
当一个 bean 仅被用作另一个 bean 的属性时,它能被声明为一个内部 bean。为了定义内部 bean,在
Spring 的基于 XML 的配置元数据中,可以在元素内使用元素。内部 bean 通常是匿名的,它们的 scope 属性一般是 prototype。

在 Spring 中如何注入一个 java 集合?
list类型用于注入一列值,允许有相同的值。
set 类型用于注入一组值,不允许有相同的值。
map类型用于注入一组键值对,键和值都可以为任意类型。
props类型用于注入一组键值对,键和值都只能为 String 类型。

什么是bean的装配?
bean的装配是指在Spring 容器中把bean组装到一起,前提是容器需要知道bean的依赖关系,通过依赖注入来把它们装配到一起。

什么是 bean 的自动装载?
Spring 容器能够自动装配相互合作的 bean,这意味着容器不需要和配置,能通过 Bean 工厂自动处理 bean 之间的协作。

解释不同方式的自动装配
no方式:是默认的方式,不进行自动装配,通过显式设置 ref 属性来进行装配。
byName方式:是通过参数名自动装配,Spring 容器在配置文件中发现 bean 的 autowire 属性被设置成 byname之后,容器试图匹配、装配和该 bean 的属性具有相同名字的 bean。
byType方式: 是通过参数类型自动装配,Spring 容器在配置文件中发现 bean 的 autowire 属性被设置成 byType之后,容器试图匹配、装配和该 bean 的属性具有相同类型的 bean。如果有多个 bean 符合条件,则抛出错误。
constructor方式:这个方式类似于 byType方式,但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。
autodetect方式:首先尝试使用 constructor 方式来自动装配,如果无法工作,则使用 byType 方式。

自动装配有哪些局限性?
仍需用和配置来定义依赖,这意味着总要重写自动装配。
不能自动装配简单的属性,如基本数据类型,String 字符串和类。
模糊特性 :自动装配不如显式装配精确,如果有可能,建议使用显式装配。

你可以在Spring中注入一个null 和一个空字符串吗?可以。

什么是基于 java 的 Spring 注解配置?给一些注解的例子
基于 Java 的配置,允许在少量的 Java 注解的帮助下,进行大部分 Spring 配置而非通过 XML 文件。以
@Configuration注解为例,它用来标记类可以当做一个 bean 的定义,被 Spring IOC 容器使用。另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个 bean 注册进 Spring 应用上下文。

什么是基于注解的容器配置
相对于 XML 文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声明。开发者通过在相应的类,方法或属性上使用注解的方式,直接在组件类中进行配置,而不是使用XML文件的方式表述 bean 的装配关系。

怎样开启注解装配?
注解装配在默认情况下是不开启的,为了使用注解装配,必须在 Spring 配置文件中配置 context:annotation-config/元素 。
@Required 注解
@Required 注解表明 bean 的属性必须在配置的时候设置,通过一个 bean 定义的显式的属性值或通过自动装配。若 @Required 注解的bean 属性未被设置,容器将抛出异常。
@Autowired 注解 @Autowired 注解提供了更细粒度的控制,包括在何处以及如何完成自动装配。它的用法和 @Required 注解一样,修饰 setter 方法、构造器、属性或者具有任意名称和多个参数的方法。
@Qualifier 注解 当有多个相同类型的 bean 却只有一个需要自动装配时,将 @Qualifier 注解和
@Autowire 注解结合使用以消除这种混淆,指定需要装配的 bean。
@RequestMapping 注解 @RequestMapping 注解用于将特定 HTTP 请求方法映射到处理相应请求的控制器中的特定类或者方法。

@Autowired和@Resource之间的区别
@Autowired注解:默认是按照类型来装配注入的,它要求依赖对象必须存在。
@Resource注解:默认是按照名称来装配注入的,只有找不到与名称匹配的bean才会按照类型来装配注入。

你可能感兴趣的:(笔记,spring)