spring

Spring的一个最大的目的就是使JAVA EE开发更加容易。同时,Spring之所以与Struts、Hibernate等单层框架不同,是因为Spring致力于提供一个以统一的、高效的方式构造整个应用,并且可以将单层框架以最佳的组合揉和在一起建立一个连贯的体系。可以说Spring是一个提供了更完善开发环境的一个框架,可以为POJO(Plain Ordinary Java Object)对象提供企业级的服务。

Spring的特性和优势

特性

  • 非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API
  • 控制反转:IOC——Inversion of Control,指的是将对象的创建权交给 Spring 去创建。使用 Spring 之前,对象的创建都是由我们自己在代码中new创建。而使用 Spring 之后。对象的创建都是给了 Spring 框架。
  • 依赖注入:DI——Dependency Injection,是指依赖的对象不需要手动调用 setXX 方法去设置,而是通过配置赋值。
  • 面向切面编程:Aspect Oriented Programming——AOP
  • 容器:Spring 是一个容器,因为它包含并且管理应用对象的生命周期
  • 组件化:Spring 实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。
  • 一站式:在 IOC 和 AOP 的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上 Spring 自身也提供了表现层的 SpringMVC 和持久层的 Spring JDBC)

优势

  • Spring 可以使开发人员使用 POJOs 开发企业级的应用程序。只使用 POJOs 的好处是你不需要一个 EJB 容器产品,比如一个应用程序服务器,但是你可以选择使用一个健壮的 servlet 容器,比如 Tomcat 或者一些商业产品。
  • Spring 在一个单元模式中是有组织的。即使包和类的数量非常大,你只要担心你需要的,而其它的就可以忽略了。
  • Spring 不会让你白费力气做重复工作,它真正的利用了一些现有的技术,像 ORM 框架、日志框架、JEE、Quartz 和 JDK 计时器,其他视图技术。
  • 测试一个用 Spring 编写的应用程序很容易,因为环境相关的代码被移动到这个框架中。此外,通过使用 JavaBean-style POJOs,它在使用依赖注入注入测试数据时变得更容易。
  • Spring 的 web 框架是一个设计良好的 web MVC 框架,它为比如 Structs 或者其他工程上的或者不怎么受欢迎的 web 框架提供了一个很好的供替代的选择。MVC 模式导致应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑)分离,同时提供这些元素之间的松散耦合。模型-(Model)封装了应用程序数据,通常它们将由 POJO 类组成。视图(View)负责渲染模型数据,一般来说它生成客户端浏览器可以解释 HTML 输出。控制器(Controller)负责处理用户请求并构建适当的模型,并将其传递给视图进行渲染。
  • Spring 对 JavaEE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。
  • 轻量级的 IOC 容器往往是轻量级的,例如,特别是当与 EJB 容器相比的时候。这有利于在内存和 CPU 资源有限的计算机上开发和部署应用程序。
  • Spring 提供了一致的事务管理接口,可向下扩展到(使用一个单一的数据库,例如)本地事务并扩展到全局事务(例如,使用 JTA)

    Core Container(Spring的核心容器)

    Spring 的核心容器是其他模块建立的基础,由 Beans 模块、Core 核心模块、Context 上下文模块和 SpEL 表达式语言模块组成,没有这些核心容器,也不可能有 AOP、Web 等上层的功能。具体介绍如下。
  • Beans 模块:提供了框架的基础部分,包括控制反转和依赖注入。
  • Core 核心模块:封装了 Spring 框架的底层部分,包括资源访问、类型转换及一些常用工具类。
  • Context 上下文模块:建立在 Core 和 Beans 模块的基础之上,集成 Beans 模块功能并添加资源绑定、数据验证、国际化、Java EE 支持、容器生命周期、事件传播等。ApplicationContext 接口是上下文模块的焦点。
  • SpEL 模块:提供了强大的表达式语言支持,支持访问和修改属性值,方法调用,支持访问及修改数组、容器和索引器,命名变量,支持算数和逻辑运算,支持从 Spring 容器获取 Bean,它也支持列表投影、选择和一般的列表聚合等。

核心流程

启动

graph TD Start["ApplicationContext 启动并刷新"] LoadDefinitions["加载并解析 BeanDefinition"] InvokeBFPP["执行 BeanFactoryPostProcessor"] RegisterBPP["注册并初始化 BeanPostProcessor 列表"] ForEachBean["为单个 Bean 开始创建"] BeforeInstDecision{"postProcessBeforeInstantiation 是否返回替代实例"} UseShortInstance["使用替代实例并跳过默认实例化与属性注入"] ShortPostAfter["对替代实例执行 postProcessAfterInitialization"] Instantiate["实例化 Bean(构造器或工厂方法)"] AfterInstDecision{"postProcessAfterInstantiation 是否返回 false(跳过属性填充)"} SkipPopulate["跳过属性填充"] ScopeDecision{"是否为单例作用域"} ExposeEarlyFactory["向 singletonFactories 注册 ObjectFactory 以支持早期引用"] PopulateProperties["填充属性并处理依赖注入"] CheckCircular{"填充过程中是否发现循环依赖"} GetEarlyRef["从 earlySingletonObjects 或 singletonFactories 获取早期引用并注入"] InvokeAware["回调 Aware 接口方法(如 BeanNameAware)"] PostProcessBeforeInit["调用 BeanPostProcessor.postProcessBeforeInitialization"] PostConstructCheck{"是否存在 @PostConstruct 方法"} PostConstructMethods["执行 @PostConstruct 标注的方法"] AfterPropertiesSetCheck{"是否实现 InitializingBean"} AfterPropertiesSet["调用 InitializingBean.afterPropertiesSet"] CustomInitCheck{"是否配置 init-method"} CustomInitMethod["执行自定义 init-method"] PostProcessAfterInit["调用 BeanPostProcessor.postProcessAfterInitialization"] NeedProxy{"是否匹配切点或 Advisor 需要创建代理"} CreateProxy["组装拦截器链并创建代理(JDK 动态代理或 CGLIB)"] BeanReady["Bean 准备就绪并对外暴露(代理或者原始对象)"] EndCreation["创建阶段完成"] Start --> LoadDefinitions --> InvokeBFPP --> RegisterBPP --> ForEachBean ForEachBean --> BeforeInstDecision BeforeInstDecision -- "是" --> UseShortInstance --> ShortPostAfter --> BeanReady BeforeInstDecision -- "否" --> Instantiate Instantiate --> AfterInstDecision AfterInstDecision -- "是" --> SkipPopulate --> InvokeAware AfterInstDecision -- "否" --> ScopeDecision ScopeDecision -- "是" --> ExposeEarlyFactory --> PopulateProperties ScopeDecision -- "否" --> PopulateProperties PopulateProperties --> CheckCircular CheckCircular -- "是" --> GetEarlyRef --> PopulateProperties CheckCircular -- "否" --> InvokeAware InvokeAware --> PostProcessBeforeInit --> PostConstructCheck PostConstructCheck -- "是" --> PostConstructMethods --> AfterPropertiesSetCheck PostConstructCheck -- "否" --> AfterPropertiesSetCheck AfterPropertiesSetCheck -- "是" --> AfterPropertiesSet --> CustomInitCheck AfterPropertiesSetCheck -- "否" --> CustomInitCheck CustomInitCheck -- "是" --> CustomInitMethod --> PostProcessAfterInit CustomInitCheck -- "否" --> PostProcessAfterInit PostProcessAfterInit --> NeedProxy NeedProxy -- "是" --> CreateProxy --> BeanReady NeedProxy -- "否" --> BeanReady BeanReady --> EndCreation

创建阶段方法/节点作用说明(要点)

  • ApplicationContext 启动并刷新:启动容器并触发后续解析与处理流程。
  • 加载并解析 BeanDefinition:读取配置类或 XML,生成每个 Bean 的元数据。
  • BeanFactoryPostProcessor:在 Bean 实例化前修改 Bean 定义或配置属性。
  • 注册 BeanPostProcessor:收集所有后置处理器,供后续实例化生命周期调用。
  • postProcessBeforeInstantiation:InstantiationAwareBeanPostProcessor 提供的钩子,可在实例化前短路并返回替代实例(常用于提前创建代理)。
  • 实例化(构造器或工厂方法):真正创建对象实例的阶段。
  • postProcessAfterInstantiation:可决定是否继续属性填充;返回 false 时跳过填充。
  • 单例早期引用与三级缓存(ExposeEarlyFactory / earlySingletonObjects 等):为解决单例属性注入的循环依赖而暴露早期引用。
  • 属性填充:解析 @Autowired、@Value 等注解并注入依赖。
  • Aware 回调:若实现 Aware 接口,容器会注入相关环境并回调接口方法。
  • postProcessBeforeInitialization:BeanPostProcessor 的前置方法,常用于准备或包装属性。
  • @PostConstruct、afterPropertiesSet、init-method:初始化回调链,按此顺序执行框架和自定义初始化逻辑。
  • postProcessAfterInitialization:后置处理器的最后一步,自动代理创建器通常在此判断是否为目标创建代理并返回代理对象。
  • 代理创建:根据切点组装拦截器链并选择代理实现,代理将替代原始对象对外暴露。

销毁

graph TD ContextClose["ApplicationContext 触发关闭"] ForEachDestroy["为容器管理的每个单例 Bean 执行销毁流程"] PreDestroyCheck{"是否存在 @PreDestroy 方法"} PreDestroyMethod["执行 @PreDestroy 标注的方法"] DisposableCheck{"是否实现 DisposableBean 接口"} DisposableDestroy["调用 DisposableBean.destroy 方法"] CustomDestroyCheck{"是否配置 destroy-method"} CustomDestroyMethod["执行自定义 destroy-method"] RemoveBean["移除 Bean 并释放资源"] EndDestroy["销毁阶段结束"] ContextClose --> ForEachDestroy ForEachDestroy --> PreDestroyCheck PreDestroyCheck -- "是" --> PreDestroyMethod --> DisposableCheck PreDestroyCheck -- "否" --> DisposableCheck DisposableCheck -- "是" --> DisposableDestroy --> CustomDestroyCheck DisposableCheck -- "否" --> CustomDestroyCheck CustomDestroyCheck -- "是" --> CustomDestroyMethod --> RemoveBean CustomDestroyCheck -- "否" --> RemoveBean RemoveBean --> EndDestroy

销毁阶段方法/节点作用说明(要点)

  • ApplicationContext 关闭:触发容器级别的销毁流程,通常在应用停止或热重启时发生。
  • @PreDestroy:在销毁前执行的注解方法,用于释放资源或注销注册。
  • DisposableBean.destroy:实现 DisposableBean 接口的销毁回调,由容器调用。
  • 自定义 destroy-method:配置于 Bean 定义的自定义销毁方法,容器在销毁阶段调用。
  • 移除并释放资源:容器完成回调后回收引用,关闭连接池等资源,完成 Bean 的销毁。

调用

graph TD Ready["Bean 已准备就绪并对外暴露"] ExternalCall["外部或客户端触发方法调用"] SelfInvoke{"是否为对象内部自我调用"} NotIntercepted["自我调用不经过代理默认直接执行目标方法"] ProxyCheck{"调用是否通过代理对象"} InterceptorChain["进入 AOP 拦截器链并按顺序执行 Advice"] BeforeAdvice["执行前置增强"] AroundAdvice["执行环绕增强(可控制目标方法执行)"] TargetInvoke["执行目标方法"] AfterReturning["执行返回增强"] AfterThrowing["执行异常增强(若抛出异常)"] ResultReturn["返回结果给调用方"] EndUsage["使用阶段结束"] Ready --> ExternalCall ExternalCall --> SelfInvoke SelfInvoke -- "是" --> NotIntercepted --> TargetInvoke SelfInvoke -- "否" --> ProxyCheck ProxyCheck -- "否" --> TargetInvoke ProxyCheck -- "是" --> InterceptorChain InterceptorChain --> BeforeAdvice --> AroundAdvice --> TargetInvoke TargetInvoke --> AfterReturning --> ResultReturn TargetInvoke --> AfterThrowing --> ResultReturn --> EndUsage

使用阶段方法/节点作用说明(要点)

  • Bean 已准备就绪:此时容器对外提供的可能是代理对象或原始对象。
  • 自我调用(self-invocation):对象内部直接调用自身方法通常绕过代理而不触发切面,若需要拦截需通过代理对象调用或获取当前代理。
  • 代理检查:方法调用到达时判断是否由代理接管;若是代理对象则进入拦截链。
  • 拦截器链:按切面定义顺序执行增强逻辑,包括前置、环绕、返回、异常等增强。
  • 环绕增强:可在调用前后执行自定义逻辑并决定是否以及何时调用目标方法。
  • 返回与异常增强:在目标方法正常返回或抛出异常后分别执行对应增强逻辑。

results matching ""

    No results matching ""