Spring 核心是一个完整的基于控制反转(IoC)的轻量级容器,用户可以使用它建立自己的应用程序。在容器上,Spring 提供大量使用的服务,高质量开源项目集成到统一的框架上。对Hibernate、MyBatis 和Struts 2等框架提供了良好的支持,能够将相应的Java Web 系统柔性整合起来,同时提供声明式事务等企业级开发。
以IoC (Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向方面编程)为内核。在Spring 中一切Java 类都是资源,而资源都是类的实例对象,容纳并管理这些Bean 的是Spring 所提供的IoC容器,所以Spring 是一种基于Bean 的编程,它深刻地改变着Java开发世界。
非Spring 核心特点
IoC(控制反转)是Spring 的核心机制,另一个称呼是(DI),这两个称呼是从两个角度描述的同一个概念。IoC是重要的面向对象编程的法则,用来削减计算机程序的耦合问题。当一个实例需要其他实例时,系统自动提供需要的实例,无需程序显式获取。依赖注入实现了组件件的解耦。
依赖注入和控制反转是含义相同,当某个Java对象(调用者)需要调用另一个Java对象(被调用者,即被依赖对象)传统方法是"new 被调用者",该方式会导致调用者和被调用者之间的耦合性增加,对后期维护不利。
使用Spring 对象后,对象实例不再由调用者创建,而是由Spring 容器来创建,Spring 容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。控制权由应用程序代码转移到了Spring 容器,控制权发生反转,即Spring 核心机制控制反转。
从Spring 容器的角度看,Spring 容器负责将被依赖对象赋值给调用者的成员变量,这相当于为调用者注入了它依赖的实例,即依赖注入。
作为Spring 核心机制的依赖注入/控制反转,改变了传统编程习惯,对组件的实例化不再由应用程序完成,转而由Spring 容器完成,需要时注入应用程序之中,从而将组件之间的依赖关系进行了解耦。这一切都离不开Spring 配置文件中使用的 元素。
该容器的设计主要基于BeanFactory和ApplicationContext两个接口
其是Spring IoC 容器的核心接口,采用经典的工厂模式。其主要功能是负责初始化各种Bean,并根据预定的配置完成对象之间依赖关系的组装,最终向使用者提供已完成装配的各种可用对象。Spring IoC容器对容器管理对象没有任何要求,无需继承某个特定类或者实现某些特定的接口
ApplicationContext 是BeanFactory的子接口之一,换句话说,BeanFactory 是Spring IoC容器所定义的最底层的接口,而ApplicationContext 是其高级接口之一,并对BeanFactory功能做出了许多有用的扩展,还添加了对国际化、资源访问、事件传播等方面的支持,使之成为Java EE 应用中首选的IoC 容器,可应用在Java App 和Java Web 中。所以在大部分的工作环境下,都会使用ApplicationContext 作为Spring IoC 的容器。
ApplicationContext 接口有三个常用的实现类:
ApplicationContext context = new ClassPathXmlApplicationContext(String configLocation);
ApplicationContext Context = new FileSystemXmlApplicationContext(String configLocation);
以上两种文件读取的方式区别在于读取Spring 配置文件的方式,第二种不再从类路径中读取路径中读取配置文件,而是通过参数指定配置文件的位置,可以获取类路径之外的资源。这种绝对路径的方式,会导致程序灵活性变差,所以不推荐使用
ServletContext servletContext = request.getSession().getServletContext();
ApplicationContext ctx = WebApplicationContextUtils.getWebApplication(servletContext);
对于Web项目,ApplicationContext 容器的实例化工作最好交给Web服务器来完成,Spring 提供如下两种方式:
Spring 支持XML 和Properties 两种格式的配置文件,在实际开发中最常用的就是XML 格式。这种配置方式通过该文件来注册和管理Bean 之间依赖关系。在Spring 中XML配置文件的根元素是,其下包含子元素,每个子元素定义一个Bean,并描述该Bean 如何被装配到Spring容器中。
元素中包含多个属性:
元素中包含多个子元素:
在XML 配置文件中,通常一个普通的Bean 只需定义id(或者name)和class 两个属性,定义Bean:
容器最重要的任务是创建并管理JavaBean 的生命周期,创建Bean 之后,需要了解Bean 在容器中是如何在不同作用域下工作的。
作用域,即生存空间或有效范围,Spring 为Bean 实例定义了多种作用域来满足不同情况下的应用需求,如下所示:
在每个Spring IoC 容器中,一个bean 定义对应一个实例对象
一个bean 定义对应多个对象实例
在一次Http 请求中,容器会返回该Bean 的同一个实例,而对于不同的用户请求,会返回该Bean 不同的实例。该作用域仅在基于web 的Spring ApplicationContext 情形下有效。
在一次Http Session 中,容器会返回该Bean 的同一个实例,而对于不同的用户请求,会返回该Bean 的同一个实例,而对于不同的用户请求,会返回不同的实例,该作用域仅在基于web 的Spring ApplicationContext 情形下有效。
在一个全局HTTP Session 中,容器会返回该Bean 的同一个实例。仅在使用portlet context 时有效
Spring 容器负责创建应用程序中Bean ,并通过依赖注入协调这些对象之间的关系。创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入(Dependency Injection)的本质,Bean 的装配方式即Bean 依赖注入。在开发基于Spring 应用时,Spring 容器支持多种形式的Bean 装配方式,如基于XML、基于注解(Annotation)的装配和自动装配等。
两种XML装配方式:属性setter 方法注入和构造方法注入。在Spring 实例化Bean 的过程中,Spring 首先会调用Bean 的默认构造方法来实例化Bean 对象,然后通过反射的方式调用setter 方法来注入属性值。属性setter 方法注入要求Bean 必须满足两点:
在Spring 中尽管使用XML 配置文件可以实现Bean的装配工作,但如果应用中Bean 的数量较多,会导致XML 配置文件过于臃肿,从而带来维护和升级方面的困难。逐步实现“零配置”。
Spring 中定义了一系列Annotation(注解):
在以上注解中,虽然@Repository、@Service、和@Controller 的功能与@Component 注解功能相同,但为了使类的标注更加清晰,在实际开发中推荐使用@Repository 标注数据访问层(DAO层)、使用@Service 标注业务逻辑层(Service层)、使用@Controller 标注控制器层(Controller层)