spring-Core-Container预览

阅读的目的?我想要从中获得什么?

​ spring按模块总结 ,ioc和aop是spring的核心

IoC container(IoC 容器)

问题

​ 思考如下问题

  • ​ 首先了解为啥需要这个模块?

  • ​ 它是啥,这个模块都有啥?

  • ​ 根据什么来的,实现了哪些规范?

IOC

从 ‘依赖反转’ 到 ‘依赖注入’
    In early 2004, Martin Fowler asked the readers of his site: when talking about Inversion of Control: “the question is, what aspect of control are [they] inverting?”

​ 2004年,Martin Fowler 对依赖反转 提出了问题,并获得结论,依赖对象的获得被反转了,基于这个结论提出了个更好的名字,依赖注入。如果对象的引用或依赖关系的管理由具体对象来完成,会导致代码高度耦合和可测试性的降低。

从 ‘对象-对象’ 到 ‘对象-IOC容器-对象’

​ 依赖反转是一种设计模式,实现有很多种方式,ioc容器式实现这个模式的载体,管理对象,对象之间的关系

对象的分类

​ 数据对象
​ 数据处理对象 不常发生变化,是系统中基础的部分,不涉及数据和状态共享的问题,依赖关系比较稳定,单例

存在于应用系统,但是对象的管理交给了容器(平台)

与EJB的关系、对比

​ 一方面,spring,ioc提供了一个基本的JavaBean容器,通过Ioc模式管理依赖关系,并通过依赖注入和AOP切面增强了
​ 为JavaBean这样的POJO对象赋予事务管理、生命周期管理等基本功能;为防止注入异常,嗨提供特定依赖的检查。

​ EJB组件需要编写远程/本地接口、Home接口以及Bean的实现类,需要依赖EJB容器 JBOSS,查找其他EJB组件也需要通过诸如JNDI这样的方式,从而造成了对EJB容器和技术规范的依赖。

​ spring把EJB组件还原成了POJO对象或者JavaBean对象,降低了应用开发对传统J2EE技术规范的依赖。
但是因为封装、抽象的太好了,反而让J2EE的初学者忽略了相关规范

​ 另一方面,通过可读的文本来完成配置,并且还能通过工具对这些配置信息进行可视化管理和浏览。并且如果耦合关系需要变动,并不需要重新修改和编译Java源代码,符合面向对象设计原则的开闭原则。如果结合OSGI还能提高应用的动态部署能力

DI

依赖查找(Dependency Lookup)

​ ID、别名、名称查找
​ BeanFactory#getBean(String) : Object

​ 类型查找
​ BeanFactory#getBean(Class) : T

​ 注解查找
​ ListableBeanFactory#getBeansWithAnnotation(Class)

​ FactoryBean 查找
​ FactoryBean#getObject()

​ ObjectFactory 查找
​ ObjectFactory#getObject()

依赖注入(Dependency Injection)

​ 方法
​ Spring @Autowired

​ Java @Resource

​ Java EE @Inject
​ 注入方式

​ 接口、setter、构造器

spring官方更推荐使用构造器的方式

    The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.

在Ex中

Type2 构造子注入的优势: (注意循环依赖的问题)

  1. “在构造期即创建一个完整、合法的对象”,对于这条Java设计原则,Type2无疑是最好的

    响应者。

  2. 避免了繁琐的setter方法的编写,所有依赖关系均在构造函数中设定,依赖关系集中呈现,

    更加易读。

  3. 由于没有setter方法,依赖关系在构造时由容器一次性设定,因此组件在被创建之后即处于

    相对“不变”的稳定状态,无需担心上层代码在调用过程中执行setter方法对组件依赖关系

    产生破坏,特别是对于Singleton模式的组件而言,这可能对整个系统产生重大的影响。

  4. 同样,由于关联关系仅在构造函数中表达,只有组件创建者需要关心组件内部的依赖关系。

    对调用者而言,组件中的依赖关系处于黑盒之中。对上层屏蔽不必要的信息,也为系统的

    层次清晰性提供了保证。

  5. 通过构造子注入,意味着我们可以在构造函数中决定依赖关系的注入顺序,对于一个大量

    依赖外部服务的组件而言,依赖关系的获得顺序可能非常重要,比如某个依赖关系注入的 先决条件是组件的DataSource及相关资源已经被设定。

Type3 设值注入的优势

  1. 对于习惯了传统JavaBean开发的程序员而言,通过setter方法设定依赖关系显得更加直

    观,更加自然。

  2. 如果依赖关系(或继承关系)较为复杂,那么Type2模式的构造函数也会相当庞大(我们需

    要在构造函数中设定所有依赖关系),此时Type3模式往往更为简洁。

  3. 对于某些第三方类库而言,可能要求我们的组件必须提供一个默认的构造函数(如Struts

    中的Action),此时Type2类型的依赖注入机制就体现出其局限性,难以完成我们期望的功能。

模块

​ 官方网站提过:

    At the heart are the modules of the core container, including a configuration model and a dependency injection mechanism. 

​ 从之前的module图可以知道有如下四部分。

image-20190628013800037

从Beans说起

​ Spring 就是面向 Bean 的编程(BOP,Bean Oriented Programming),Bean 在 Spring 中作用就像 Object 对 OOP 的意义一样,没有对象的概念就像没有面向对象编程,Spring 中没有 Bean 也就没有 Spring 存在的意义

​ 这个包下的所有类主要解决了三件事:Bean 的定义、Bean 的创建以及对 Bean 的解析

Bean 的创建

​ Spring Bean 的创建时典型的工厂模式,它的顶级接口是 BeanFactory

BeanFactory 有三个子类:

ListableBeanFactory 接口 :表示这些 Bean 是可列表的

HierarchicalBeanFactory :表示的这些 Bean 是有继承关系的,有父bean

AutowireCapableBeanFactory :接口定义 Bean 的自动装配规则

​ 上述的接口共同定义了 Bean 的集合、Bean 之间的关系、以及 Bean 行为,它们的默认实现类是 DefaultListableBeanFactory

​ todo ==DefaultListableBeanFactory的子类分析==

Bean 的定义

​ Bean 的定义主要有 BeanDefinition 描述,主要来自两方面

​ XML定义,

​ 注解扫描 @Service @Entity @Bean @Configuration

Bean 的解析

​ 把xml解析成Resource类

​ todo ==Resource的类分析==

Spring Bean 封装机制

​ Spring 从核心而言,是一个 DI 容器,其设计哲学是提供一种无侵入式的高扩展性框架。即无需代码中涉及 Spring 专有类(指Bean),即可将其纳入 Spring 容器进行管理。

​ 作为对比,EJB 则是一种高度侵入性的框架规范,它制定了众多的接口和编码规范,要求实现者必须 遵从。侵入性的后果就是,一旦系统基于侵入性框架设计开发,那么之后任何脱离这个框架的企图都将付 出极大的代价。

​ Spring 大量引入了 Java 的 Reflection 机制,通过动态 调用的方式避免硬编码方式的约束,并在此基础上建立了其核心组件 BeanFactory,以此作为其依赖注入 机制的实现基础。

org.springframework.beans 包中包括了这些核心组件的实现类,核心中的核心为 BeanWrapper
和 BeanFactory 类。

BeanWrapper

​ 这个BeanWrapper的功能很简单,提供一个设置JavaBean属性的通用方法, 动态设置一个对象属性

Bean Factory

​ 负责创建并维护Bean实例。

Bean Factory负责根据配置文件创建Bean实例,可以配置的项目有:

  1. Bean属性值及依赖关系(对其他Bean的引用) property
  2. Bean创建模式(是否Singleton模式,即是否只针对指定类维持全局唯一的实例) singleton
  3. Bean初始化和销毁方法 init-method destroy-method
  4. Bean的依赖关系。 depends-on(通过depends-on指定其依赖关系可保证在此Bean加载之前,首先对depends-on所指定的资源进行加载)

容器Context

​ BeanFactory提供了针对Java Bean的管理功能,而ApplicationContext提供了一个更为框架化的 实现(从上面的示例中可以看出,BeanFactory的使用方式更加类似一个API,而非Framework style)。

​ ApplicationContext覆盖了BeanFactory的所有功能,并提供了更多的特性。此外, ApplicationContext为与现有应用框架相整合,提供了更为开放式的实现(如对于Web应用,我们可以在 web.xml中对ApplicationContext进行配置)。

​ ApplicationContext 是 Context 的顶级父类,他除了能标识一个应用环境的基本信息外,他还继承了五个接口,这五个接口主要是扩展了 Context 的功能。下面是 Context 的类结构图

image-20190303180157960

相对BeanFactory而言,ApplicationContext提供了以下扩展功能:

  1. 国际化支持 我们可以在Beans.xml文件中,对程序中的语言信息(如提示信息)进行定义,将程序中的提示 信息抽取到配置文件中加以定义,为我们进行应用的各语言版本转换提供了极大的灵活性。
(native2ascii messages_zh_CN.properties msg.txt)
  1. 资源访问 支持对文件和URL的访问。
  2. 事件传播 事件传播特性为系统中状态改变时的检测提供了良好支持。
  3. 多实例加载 可以在同一个应用中加载多个Context实例。

Core

​ 其实 Core 就是发现、建立和维护每个 Bean 之间的关系所需要的一些列的工具,从这个角度看来,Core 这个组件叫 Util 更能让你理解。

下图是 Resource 相关的类结构图:

image-20190303181354519

​ 从上图可以看出 Resource 接口封装了各种可能的资源类型,也就是对使用者来说屏蔽了文件类型的不同。

​ 对资源的提供者来说,如何把资源包装起来交给其他人用这也是一个问题,我们看到 Resource 接口继承了 InputStreamSource 接口,这个接口中有个 getInputStream 方法,返回的是 InputStream 类。这样所有的资源都被可以通过 InputStream 这个类来获取,所以也屏蔽了资源的提供者。

​ 另外还有一个问题就是加载资源的问题,也就是资源的加载者要统一,从上图中可以看出这个任务是由 ResourceLoader 接口完成,他屏蔽了所有的资源加载者的差异,只需要实现这个接口就可以加载所有的资源,他的默认实现是 DefaultResourceLoader。

SpEL

如何创建 BeanFactory 工厂

如何创建 Bean 实例并构建 Bean 的关系网

规范

实现了哪些规范?

Java Beans JSR—101

内省

​ 基础核心特性:反射(Reflection)

​ 附加特性:引用(Reference)
​ Reference
​ SoftReference
​ WeakReference
​ PhantomReference
​ FinalReference
​ BeanInfo
​ BeanDescriptor
​ PropertyDescriptor
​ 事件: PropertyChangeEvent
​ java.util.EventObject

​ 监听器: PropertyChangeListener
​ java.util.EventListener
​ MethodDescriptor

Dependency Injection (JSR 330)

Bean Validation (JSR 303). JSR-349 JSR-380 1.0 1.1 2.0

Common Annotations (JSR 250)

JSR-305 meta-annotations

API-Doc


https://docs.spring.io/spring/docs/5.1.5.RELEASE/javadoc-api/

beans

Package org.springframework.beans Description

This package contains interfaces and classes for manipulating Java beans. It is used by most other Spring packages.

A BeanWrapper object may be used to set and get bean properties, singly or in bulk.

The classes in this package are discussed in Chapter 11 of Expert One-On-One J2EE Design and Development by Rod Johnson (Wrox, 2002).

context

Package org.springframework.context Description

This package builds on the beans package to add support for message sources and for the Observer design pattern, and the ability for application objects to obtain resources using a consistent API.

There is no necessity for Spring applications to depend on ApplicationContext or even BeanFactory functionality explicitly. One of the strengths of the Spring architecture is that application objects can often be configured without any dependency on Spring-specific APIs.

core

Package org.springframework.core Description

Provides basic classes for exception handling and version detection, and other core helpers that are not specific to any part of the framework.


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 951488791@qq.com

文章标题:spring-Core-Container预览

字数:3k

本文作者:zhengyumin

发布时间:2019-03-03, 14:51:56

最后更新:2020-04-02, 23:07:54

原始链接:http://zyumin.github.io/2019/03/03/spring-Core-Container%E9%A2%84%E8%A7%88/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。