spring 复习整理一
spring 复习整理一(仗剑走天涯)
小科普
DTD
DTD(Document Type Definition)即文档类型定义,是一种XML约束模式语言,是XML文件的验证机制
1 |
DTD声明始终以!DOCTYPE开头,空一格后跟着文档根元素的名称。
根元素名:configuration。所以每一个标签库定义文件都是以taglib为根元素的,否则就不会验证通过。
PUBLIC “-//mybatis.org//DTD Config 3.0//EN,这是一个公共DTD的名称(私有的使用SYSTEM表示)。这个东西命名是有些讲究的。首先它是以”-“开头的,表示这个DTD不是一个标准组织制定的。(如果是ISO标准化组织批准的,以“ISO”开头)。接着就是双斜杠“//”,跟着的是DTD所有者的名字,很明显这个DTD是MyBatis公司定的。接着又是双斜杠“//”,然后跟着的是DTD描述的文档类型,可以看出这份DTD描述的是DTD Config 3.0的格式。再跟着的就是“//”和ISO 639语言标识符。
绿色的字”http://mybatis.org/dtd/mybatis-3-config.dtd",表示这个DTD的位置
XSD
文档结构描述XML Schema Definition 缩写,这种文件同样可以用来定义我们xml文件的结构
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" |
第一行的xmlns代表了一个xml文件中的一个命名空间,通常是一个唯一的字符串,一般使用一个url
xmlns:xsi
=”http://www.w3.org/2001/XMLSchema-instance" 冒号后面的为命名
xmlns:xsi 定义了一个命名空间前缀 xsi 对应的唯一字符串 http://www.w3.org/2001/XMLSchema-instance。但这个 xmlns:xsi 在不同的 xml 文档中似乎都会出现。 这是因为, xsi 已经成为了一个业界默认的用于 XSD((XML Schema Definition) 文件的命名空间。 而 XSD 文件(也常常称为 Schema 文件)是用来定义 xml 文档结构的。剩余两行的目的在于为我们的命名空间指定对应的xsd文件
Why spring?
更快、更容易、更安全
spring特性
Core technologies
: dependency injection, events, resources, i18n, validation, data binding, type conversion, SpEL, AOP.
核心技术:包括依赖注入、事件模型、资源处理、国际化、数据绑定和验证、类型转化、spring表达式、面向切面编程。核心技术是一切的关键,后边衍生的多个特性都是依托于核心技术。
Testing
: mock objects, TestContext framework, Spring MVC Test, WebTestClient.
Data Access
: transactions, DAO support, JDBC, ORM, Marshalling XML.
Spring MVC and Spring WebFlux web frameworks
.
Integration
: remoting, JMS, JCA, JMX, email, tasks, scheduling, cache.
Languages
: Kotlin, Groovy, dynamic languages
IOC容器
可以管理对象的生命周期、对象与对象之间的依赖关系
POJO
简单java对象
POJO的含义
没有继承任何类、也没有实现任何接口,更没有被其它框架侵入的java对象。不允许有业务方法,也不能携带connection之类的方法,实际就是普通JavaBeans
javaBean
JavaBean是一种JAVA语言写成的可重用组件。JavaBean符合一定规范编写的Java类,不是一种技术,而是一种规范
javaBean的约定
所有属性为private。
这个类必须有一个公共的缺省构造函数。即是提供无参数的构造器。
这个类的属性使用getter和setter来访问,其他方法遵从标准命名规范。
这个类应是可序列化的。实现serializable接口
POJO和javaBean的区别
POJO | JAVABean |
---|---|
除了Java语言强加的限制外,它没有其他特殊限制 | 这是一个特殊的POJO,它有一些限制 |
它没有对成员提供太多控制 | 它提供对成员的完全控制 |
它可以实现Serializable接口 | 它应该实现可序列化的接口 |
可以通过字段名称访问字段 | 字段只能由getter和setter访问 |
字段可以具有任何可见性 | 字段只有私人可见性 |
可能/可能没有no-arg构造函数 | 它必须具有无参数构造函数 |
当您不想限制成员并让用户完全访问您的实体时使用它 | 当您要向用户提供您的实体,但仅向实体的一部分提供服务时,将使用它 |
POJO类和Bean均用于定义Java对象,以提高其可读性和可重用性。POJO没有其他限制,而bean是具有某些限制的特殊POJO
SpringBean
SpringBean是受Spring管理的对象,所有能受Spring容器管理的对象都可以成为SpringBean。Spring中的bean,是通过配置文件、javaconfig等的设置,由Spring自动实例化,用完后自动销毁的对象
SpringBean和JavaBean的区别
用处不同:传统javabean更多地作为值传递参数,而spring中的bean用处几乎无处不在,任何组件都可以被称为bean。
写法不同:传统javabean作为值对象,要求每个属性都提供getter和setter方法;但spring中的bean只需为接受设值注入的属性提供setter方法。
生命周期不同:传统javabean作为值对象传递,不接受任何容器管理其生命周期;spring中的bean有spring管理其生命周期行为。
Entity Bean
Entity Bean是域模型对象,用于实现O/R映射,负责将数据库中的表记录映射为内存中的Entity对象,事实上,创建一个Entity Bean对象相当于新建一条记录,删除一个 Entity Bean会同时从数据库中删除对应记录,修改一个Entity Bean时,容器会自动将Entity Bean的状态和数据库同步
举个例子
加入有个user对象 它与数据库字段一一对应 那么这个user对象就是一个Entity Bean
也是一个POJO
还是一个javaBean
你要是再把它放到Spring中 那么它还是一个SpringBean
spring的两个主要接口
依赖
1 | <!-- spring核心--> |
BeanFactory
1 | public interface BeanFactory {} |
提供了一种高级的配置机制,能够管理任何类型的对象。 ApplicationContext是BeanFactory的子接口
ApplicationContext
1 | public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {} |
BeanFactory提供了容器的基本功能,而ApplicationContext添加了更多特定于企业的功能
更容易与Spring的AOP特性集成
消息资源处理(用于国际化) 解析消息的能力 支持国际化 继承自MessageSource接口
事件发布 向注册侦听器发布事件的能力 继承自ApplicationEventPublisher接口
应用程序层特定的上下文,如WebApplicationContext用于web应用程序
以通用方式加载文件资源的能力 继承自org.springframe .core.io.ResourceLoader接口
元数据
传统上以简单而直观的XML格式提供 要告诉Spring容器如何去【实例化、配置和组装】应用程序中的对象
基本配置
1 |
|
Bean概述
Spring IoC容器管理一个或多个bean。 这些bean是使用您提供给容器的配置元数据创建的
Bean的命名
每个bean都有【一个或多个】标识符。 这些标识符在承载bean的容器(ioc容器)中必须是唯一的。 bean通常只有一个标识符。 但是,如果需要多个,则可以考虑使用别名
id
属性允许您指定一个id
name
属性可以多个 用逗号空格分开
Bean别名
1 | <alias name="userDao" alias="userDao2"/> |
实例化Bean
beanDifination本质上是描述了一个bean是如何被创建的。 当被请求时,容器会查看指定bean的定义,并使用由该beanDifination封装的配置元数据来创建(或获取)实际对象
使用构造函数实例化
1 | <bean id="userDao" name="userDao" |
使用静态工厂实例化
在使用【静态工厂方法】创建的bean时,使用【class】属性指定包含【一个静态工厂方法】的类,并使用名为【factory-method】的属性指定工厂方法本身的名称
1 | <bean id="userDao" name="userDao" |
使用实例工厂实例化
该方法类似于通过(静态工厂方法)实例化所需的bean,容器同样可以使用【实例工厂方法】调用【非静态方法】创建一个新的bean。 要使用这种机制,请将【class】属性保留为空,并在【factory-bean】属性中指定当前容器中包含要调用的实例方法的bean的名称。 使用“factory-method”属性设置工厂方法本身的名称
1 | <bean id="userDao" name="userDao" |
依赖注入(Dependency Injection)
依赖注入(DI)是一个【过程】在此过程中,对象仅通过【构造函数参数】、【工厂方法参数】等来确定它们的依赖项。 然后容器在创建bean时注入这些依赖项。 从根本上说,这个过程与bean本身相反(因此得名”控制反转”)
大大实现了解耦
举个例子
就好比对象A依赖于B 但是B依赖于C 正常的话就是 在B类先new一个C 然后在A类new一个B然后将放入A的有参构造中 顺序是c–>b–>a 但是spring容器不知道先后依赖顺序 他是a依赖于b 就在容器中找b创建 然后b依赖c 就在容器中找c 顺序是 a–>b–>c 这也就是另一种称呼的来源 控制反转 就像反转了一样
DI的主要两种方式
基于构造函数的依赖注入
通过容器调用带有许多参数的构造器来实现的
1 | <bean name="userDao" class="com.dream.xiaobo.dao.UserDao"/> |
基于setter的注入
通过容器在【调用无参数构造函数】或【无参数“静态”工厂方法】实例化bean后调用bean上的setter方法来实现的
1 | <bean name="userDao" class="com.dream.xiaobo.dao.UserDao"/> |
直接值
1 | <bean name="user" class="com.dream.xiaobo.entity.User"> |
null值和空字符串
- 空字符串
1 | <bean class="ExampleBean"> |
- null
1 | <bean class="ExampleBean"> |
延迟初始化的 Bean
延迟初始化的bean告诉IoC容器在【第一次请求】时创建bean实例,而不是在启动时
在XML中,这种行为是由
1 | <bean name="userDao" class="com.dream.xiaobo.dao.UserDao" lazy-init="true"/> |
当一个【延迟初始化的bean】是一个没有延迟初始化的单例bean的依赖时,ApplicationContext会在启动时创建这个延迟初始化的bean,因为它必须满足单例bean的依赖, 延迟初始化的bean会被注入到没有延迟初始化的其他单例bean中
自动装配
当使用基于xml的配置元数据时,您可以使用
自动装配的四种模式
运行方式 | 解释 |
---|---|
no | (默认)没有自动装配。 Bean引用必须由【ref】元素定义。 对于较大的部署,不建议更改默认设置,因为【明确指定协作者】可以提供更大的控制和清晰度。 在某种程度上,它记录了系统的结构 |
byName | 通过属性名自动装配。 Spring寻找与需要自动连接的属性同名的bean。 例如,如果一个beanDifination被设置为按名称自动装配,并且它包含一个“master”属性(也就是说,它有一个“setMaster(..)”方法),Spring会寻找一个名为“master”的beanDifination并使用它来设置属性 |
byType | 如果容器中恰好有一个属性类型的bean,则允许自动连接属性。 如果存在多个,则抛出异常,这表明您不能对该bean使用’ byType ‘自动装配。 如果没有匹配的bean,则不会发生任何事情(没有设置属性) |
constructor | 类似于’ byType ‘,但适用于构造函数参数。 如果容器中没有一个构造函数参数类型的bean,则会引发致命错误 |
自动装配的优点
自动装配可以显著减少指定属性或构造函数参数的需要
自动装配可以随着对象的发展更新配置
从自动装配中排除Bean
在每个bean的基础上,您可以将一个bean排除在自动装配之外。 在Spring的XML格式中,将
1 | public class User { |
1 | <bean class="com.dream.xiaobo.dao.AddressDao" name="addressDao" /> |
循环依赖
流程
创建A时发现成员变量依赖B 首先去一级缓存中查找 如果有直接填充 没有 再去二级缓存中去查找 二级缓存中有 填充 没有 在去容器中查找 容器中如果有 直接进行填充 如果没有创建B 然后B同理A
你知道的越多 你不知道的越多 嘿 我是小博 带你一起看我目之所及的世界……
本文标题:spring 复习整理一
发布时间:2022年04月20日 - 19:28
最后更新:2022年04月20日 - 20:23
原始链接:https://codexiaobo.github.io/posts/2522155561/
许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。