|
@@ -0,0 +1,193 @@
|
|
|
+## 第六章:Spring IoC依赖注入(Dependency Injection)
|
|
|
+
|
|
|
+## 依赖注入的模式和类型
|
|
|
+
|
|
|
+- 手动模式 - 配置或者编程的方式,提前安排注入规则
|
|
|
+ - XML 资源配置元信息
|
|
|
+ - Java 注解配置元信息
|
|
|
+ - API 配置元信息
|
|
|
+- 自动模式 - 实现方提供依赖自动关联的方式,按照內建的注入规则
|
|
|
+ - Autowiring(自动绑定)
|
|
|
+
|
|
|
+## 依赖注入类型
|
|
|
+
|
|
|
+| 依赖注入类型 | 配置元数据举例 |
|
|
|
+| ------------ | -------------------------------------------------- |
|
|
|
+| Setter 方法 | `<proeprty name="user" ref="userBean"/>` |
|
|
|
+| 构造器 | `<constructor-arg name="user" ref="userBean" />` |
|
|
|
+| 字段 | `@Autowired User user;` |
|
|
|
+| 方法 | `@Autowired public void user(User user) { ... }` |
|
|
|
+| 接口回调 | `class MyBean implements BeanFactoryAware { ... }` |
|
|
|
+
|
|
|
+## 自动绑定(Autowiring)模式,Autowiring modes
|
|
|
+
|
|
|
+参考枚举:`org.springframework.beans.factory.annotation.Autowire`
|
|
|
+
|
|
|
+| 模式 | 说明 |
|
|
|
+| ----------- | ------------------------------------------------------------ |
|
|
|
+| no | 默认值,未激活 Autowiring,需要手动指定依赖注入对象。 |
|
|
|
+| byName | 根据被注入属性的名称作为 Bean 名称进行依赖查找,并将对象设置到该属性。 |
|
|
|
+| byType | 根据被注入属性的类型作为依赖类型进行查找,并将对象设置到该属性。 |
|
|
|
+| constructor | 特殊 byType 类型,用于构造器参数。 |
|
|
|
+
|
|
|
+## setter方法注入
|
|
|
+
|
|
|
+* 实现方法
|
|
|
+ * 手动模式
|
|
|
+ * XML资源配置元信息
|
|
|
+ * JAVA注解配置元信息
|
|
|
+ * API配置元信息
|
|
|
+ * 自动模式
|
|
|
+ * byName
|
|
|
+ * byType
|
|
|
+
|
|
|
+## 构造器注入
|
|
|
+
|
|
|
+* 实现方法
|
|
|
+
|
|
|
+ * 手动模式
|
|
|
+ * XML资源配置元信息
|
|
|
+ * JAVA注解配置元信息
|
|
|
+ * API配置元信息
|
|
|
+
|
|
|
+ * 自动模式
|
|
|
+ * constructor -- 特殊的bytype
|
|
|
+
|
|
|
+## 字段注入
|
|
|
+
|
|
|
+* 实现方法
|
|
|
+ * 手动方式
|
|
|
+ * JAVA注解配置元信息
|
|
|
+ * @Autowired
|
|
|
+ * @Resource
|
|
|
+ * @inject (可选)
|
|
|
+
|
|
|
+## 方法注入
|
|
|
+
|
|
|
+* 实现方法
|
|
|
+ * 手动模式
|
|
|
+ * JAVA注解配置元信息
|
|
|
+ * @Autowired
|
|
|
+ * @Resource
|
|
|
+ * @inject (可选)
|
|
|
+ * Bean
|
|
|
+
|
|
|
+## Aware 系列接口回调
|
|
|
+
|
|
|
+| 內建接口 | 说明 |
|
|
|
+| ------------------------------ | -------------------------------------------------------- |
|
|
|
+| BeanFactoryAware | 获取 IoC 容器 - BeanFactory |
|
|
|
+| ApplicationContextAware | 获取 Spring 应用上下文 - ApplicationContext 对象 |
|
|
|
+| EnvironmentAware | 获取 Environment 对象 |
|
|
|
+| ResourceLoaderAware | 获取资源加载器 对象 - ResourceLoader |
|
|
|
+| BeanClassLoaderAware | 获取加载当前 Bean Class 的 ClassLoader |
|
|
|
+| BeanNameAware | 获取当前 Bean 的名称 |
|
|
|
+| MessageSourceAware | 获取 MessageSource 对象,用于 Spring 国际化 |
|
|
|
+| ApplicationEventPublisherAware | 获取 ApplicationEventPublishAware 对象,用于 Spring 事件 |
|
|
|
+| EmbeddedValueResolverAware | 获取 StringValueResolver 对象,用于占位符处理 |
|
|
|
+
|
|
|
+## 依赖注入类型选择
|
|
|
+
|
|
|
+- 低依赖:构造器注入
|
|
|
+- 多依赖:Setter 方法注入 --- 注入时机没有顺序
|
|
|
+- 便利性:字段注入
|
|
|
+- 声明类:方法注入 --- 不建议使用,建议配置@Bean使用
|
|
|
+
|
|
|
+## 各种类型注入
|
|
|
+
|
|
|
+- 基础类型
|
|
|
+ - 原生类型(Primitive):boolean、byte、char、short、int、float、long、double
|
|
|
+ - 标量类型(Scalar):Number、Character、Boolean、Enum、Locale、Charset、Currency、Properties、UUID
|
|
|
+ - 常规类型(General):Object、String、TimeZone、Calendar、Optional 等
|
|
|
+ - Spring 类型:Resource、InputSource、Formatter 等
|
|
|
+- 集合类型
|
|
|
+ - 数组类型(Array):原生类型、标量类型、常规类型、Spring 类型
|
|
|
+ - 集合类型(Collection)
|
|
|
+ - Collection:List、Set(SortedSet、NavigableSet、EnumSet)
|
|
|
+ - Map:Properties
|
|
|
+- 限定注入
|
|
|
+ - 使用注解 @Qualifier 限定
|
|
|
+ - 通过 Bean 名称限定
|
|
|
+ - 通过分组限定
|
|
|
+ - 基于注解 @Qualifier 扩展限定
|
|
|
+ - 自定义注解,如 Spring Cloud @LoadBalanced
|
|
|
+- 延迟依赖注入
|
|
|
+ - 使用API ObjectFactory 延迟注入
|
|
|
+ - 单一类型
|
|
|
+ - 集合类型
|
|
|
+
|
|
|
+ - 使用API ObjectProvider 延迟注入(推荐)
|
|
|
+ - 单一类型
|
|
|
+ - 集合类型
|
|
|
+
|
|
|
+- 使用 API ObjectFactory 延迟注入
|
|
|
+ - 单一类型
|
|
|
+ - 集合类型
|
|
|
+- 使用 API ObjectProvider 延迟注入(推荐)
|
|
|
+ - 单一类型
|
|
|
+ - 集合类型
|
|
|
+
|
|
|
+## 依赖处理过程
|
|
|
+
|
|
|
+- 入口 - `DefaultListableBeanFactory#resolveDependency`
|
|
|
+- 依赖描述符 - Dependency Descriptor
|
|
|
+- 自定绑定候选对象处理器 - AutowireCandidateResolver
|
|
|
+
|
|
|
+## @autowired注入过程
|
|
|
+
|
|
|
+* 元信息解析
|
|
|
+* 依赖查找(依赖处理)
|
|
|
+* 依赖注入(字段,方法)
|
|
|
+
|
|
|
+@Autowired、@Inject 注入,参考 `AutowiredAnnotationBeanPostProcessor`
|
|
|
+
|
|
|
+## Java通用注解注入原理:
|
|
|
+
|
|
|
+- `CommonAnnotationBeanPostProcessor`
|
|
|
+- 注入注解
|
|
|
+ - javax.xml.ws.WebServiceRef
|
|
|
+ - javax.ejb.EJB
|
|
|
+ - javax.annotation.Resource
|
|
|
+- 生命周期注解
|
|
|
+ - javax.annotation.PostConstruct
|
|
|
+ - javax.annotation.PreDestroy
|
|
|
+
|
|
|
+## 自定义依赖注入注解
|
|
|
+
|
|
|
+- 基于 `AutowiredAnnotationBeanPostProcessor` 实现
|
|
|
+- 自定义实现
|
|
|
+ - 生命周期处理
|
|
|
+ - InstantiationAwareBeanPostProcessor
|
|
|
+ - MergedBeanDefinitionPostProcessor
|
|
|
+ - 元数据
|
|
|
+ - InjectedElement
|
|
|
+ - InjectionMetadata
|
|
|
+- `org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor`
|
|
|
+ - org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
|
|
|
+ - `@Autowired`
|
|
|
+ - `@Value`
|
|
|
+ - `@Inject`
|
|
|
+ - org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
|
|
|
+ - `@PostConstruct`
|
|
|
+ - `@PreDestroy`
|
|
|
+
|
|
|
+初始化 Bean 时,`AutowiredAnnotationBeanPostProcessor` 先解析 Bean 中的依赖(`@Autowire`,`@Value`),然后 `CommonAnnotationBeanPostProcessor` 调用初始化方法 `@@PostConstruct`
|
|
|
+
|
|
|
+将 `@Bean` 方法设置为 `static` ,可以让 Bean 提前初始化。
|
|
|
+
|
|
|
+- 依赖查找:`ApplicationContext#getBean`
|
|
|
+- 依赖处理过程:`org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency`
|
|
|
+
|
|
|
+# 面试题精选
|
|
|
+
|
|
|
+1、有多少种依赖注入的方式?
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+2、偏好构造器注入还是setter注入?
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+3、spring依赖注入的来源有哪些?
|
|
|
+
|
|
|
+
|