Spring Framework总结

Spring 框架

简介

Spring框架是一个开源的容器性质的轻量级框架。主要有三大特点:容器、IOC(控制反转)、AOP(面向切面编程)。
Spring框架至今已集成了20多个模块。这些模块主要被分如下图所示的核心容器、数据访问/集成,、Web、AOP(面向切面编程)、工具、消息和测试模块。

IOC

IoC(Inverse of Control): 反转控制的概念,就是将原本在程序中手动创建对象的控制权,交由Spring框架管理,简单说,就是创建对象控制权被反转到了Spring框架。作用是实现了程序的解耦合。BeanFactory是Spring IoC容器的核心接口。

用户新建对象时不需要new相关对象,而是由框架自己去生产,这里用的就是java的反射机制,通过反射在运行时动态的去创建、调用对象。spring就是根据配置文件在运行时动态的去创建对象,并调用对象的方法的。

IOC是一种编程思想,DI是一种实现方式。

DI

DI(Dependency Injection):依赖注入的概念,是IoC的其中一个内容,指在容器实例化对象的时候主动地将被调用者注入给调用对象,比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。

BeanFactory和ApplicationContext

BeanFactory和ApplicationContext是Spring的两大核心接口,而ApplicationFactory继承了BeanFactory接口;它们是Spring容器,实例化与管理Bean。

(1)BeanFactory:是Spring里面最底层的接口,提供了最简单的容器的功能,负责读取bean配置文档,管理bean的加载与实例化,维护bean之间的依赖关系,负责bean的生命周期,但是无法支持spring的aop功能和web应用。

(2)ApplicationContext接口作为BeanFactory的派生,因而具有BeanFactory所有的功能。而且ApplicationContext还在功能上做了扩展,以一种更面向框架的方式工作以及对上下文进行分层和实现继承,相较于BeanFactorty,ApplicationContext还提供了以下的功能:

  • 默认初始化所有的Singleton,也可以通过配置取消预初始化。

  • 继承MessageSource,因此支持国际化。

  • 资源访问,比如访问URL和文件。

  • 事件机制。

  • 同时加载多个配置文件。

  • 以声明式方式启动并创建Spring容器。

  • 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。

BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的Spring的配置问题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常。

而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。 ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。

相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。

Spring中Bean的作用域

singleton

当一个bean的作用域为singleton, 那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。

prototype

Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean() 方法)时都会创建一个新的bean实例。根据经验,对所有有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用 singleton作用域

request

在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例, 它们依据某个bean定义创建而成。该作用 域仅在基于web的Spring ApplicationContext情形下有效。

session

在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

global session

在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于 web的Spring ApplicationContext情形下有效。

Spring Bean的生命周期

bean的生命周期包括bean的定义、bean的初始化、bean的调用和bean的销毁。

  • Spring容器从XML文件中读取bean的定义并实例化bean。
  • Spring根据bean的定义填充所有的属性。
  • 调用BeanNameAware的setBeanName方法。
  • 调用BeanFactoryAware的setBeanFactory方法。
  • 调用BeanPostProcessor的postProcesserBeforeInitialization方法。
  • 调用InitializingBean的afterPropertiesSet方法。
  • 调用<\bean>的init-method属性指定的初始化方法。
  • 调用BeanPostProcessor的postProcesserAfterInitialization方法。
  • 容器初始化成功,程序执行,业务逻辑调用后,下面销毁容器。
  • 调用DisposableBean的destroy方法。
  • 调用\<bean>的destroy-method属性指定的销毁方法。
  • \<bean>有两个重要的属性init-method和destroy-method用来定制初始化和注销方法,它们也有相应的注解@PostConstruct和@PreDestroy。

Spring框架中属性注入有哪几种方式

Spring中的输入注入方式包括set方法注入、构造函数注入、p名称空间注入、spel注入,除此之外,还包括复杂方式注入,如数组、List、Map、Properties等属性的注入。

Spring注解方式

在使用注解之前,要先在spring的主配置文件中通过Context:component-scan标签来开启使用注解的开关。

将对象注册到IoC容器的注解方式

@Component()、@Service()、@Controller()、@Respository

注解方式指定对象的作用范围

@Scope 如: @Scope(scopeName=”singleton”)

注解方式的依赖注入

值类型注入

过@Value()注解来完成,该注解既可以声明在属性上,也可以声明在方法上,建议声明在方法上,但是更多的人会声明在属性上,因为更方便。

引用类型注入

引用类型注入可以通过三种注解方式来完成,分别为:@Autowired、@Autowired和@Qualifier()二者结合、@Resource()。建议使用@Resource()

@Required

该注解表明bean的属性必须在配置的时候设置,若@Required注解的bean属性未被设置,容器将抛出BeanInitializationException。注意@Required只能设置在setter方法上。

@Autowired

该注解可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作,默认是按类型进行装配。在类成员变量上加上该注解时,就可以去掉相应的getter和setter方法了,Spring将直接采用Java反射机制对成员变量进行自动注入。

@Qualifier

当有多个相同类型的bean却只有一个需要自动装配时,将@Qualifier注解和@Autowired注解结合使用以消除这种混淆,指定需要装配的确切的bean。

@Resource

与@Autowired不同的是该注解默认按照名称装配,当找不到与名称匹配的bean时才会按照类型装配。注意如果没有指定name属性,并且按照默认的名称仍然找不到依赖的对象时候,会回退到按照类型装配,但一旦指定了name属性,就只能按照名称装配了。

AOP

AOP (aspect oriented programing)面向切片编程的概念,将程序纵向重复的代码横向抽取出来,作用时降低耦合,Spring中的AOP思想体现在能够为容器中管理的对象生成动态代理对象。

通知(Advice)

就是想要的功能,也就是上说的安全、事物、日子等。你给先定义好,然后再想用的地方用一下。Spring可以应用五种类型的通知:

  • before:前置通知,在一个方法执行前被调用。
  • after:在方法执行之后调用的通知,无论方法执行是否成功。
  • after-returning:仅当方法成功完成后执行的通知。
  • after-throwing:在方法抛出异常退出时执行的通知。
  • around:在方法执行之前和之后调用的通知。

连接点(JoinPoint)

就是Spring允许是通知(Advice)的地方,基本每个方法的前、后(两者都有也行),或抛出异常时都可以是连接点,Spring只支持方法连接点。

切入点(Pointcut)

上面说的连接点的基础上,来定义切入点,你的一个类里,有15个方法,那就有十几个连接点了对吧,但是你并不想在所有方法附件都使用通知(使用叫织入,下面再说),你只是想让其中几个,在调用这几个方法之前、之后或者抛出异常时干点什么,那么就用切入点来定义这几个方法,让切入点来筛选连接点,选中那几个你想要的方法。

切面(Aspect)

切面是通知和切入点的结合。通知说明了干什么和什么时候干(什么时候通过方法名中的befor,after,around等就能知道),二切入点说明了在哪干(指定到底是哪个方法),这就是一个完整的切面定义。

织入(weaving)

把切面应用到目标对象来创建新的代理对象的过程。

引入(introduction)

允许我们在已存在的类中增加新的方法和属性。

代理(proxy)

通知目标对象后创建的对象。从客户端的角度看,代理对象和目标对象是一样的。

Spring MVC

Spring MVC是一个基于MVC架构的用来简化web应用程序开发的应用开发框架,它是Spring的一个模块。在web模型中,MVC是一种很流行的架构,通过把Model,View,Controller分离,把较为复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。

执行流程

  • 用户发送请求至前端控制器DispatcherServlet;
  • DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
  • 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
  • DispatcherServlet通过HandlerAdapter处理器适配器调用处理器;
  • 执行处理器(Handler,也叫后端控制器);
  • Handler执行完成返回ModelAndView;
  • HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
  • DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
  • ViewResolver解析后返回具体View;
  • DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
  • DispatcherServlet响应用户。