IoC (Inversion of Control,控制反转)与DI(Dependency Injecion,依赖注入)

用于对象间解耦,如在以前若对象A依赖B则需要在A中负责B的创建初始化等工作,现在有了IoC容器(如Spring的)专门负责对象的创建等生命周期的管理,A中只要声明一个B对象就可使用而不再需要负责初始化B(@Autowired等)。“反转”体现在A获得依赖对象B的过程由之前的主动行为变成了被动行为,即获得依赖对象的过程“反转了”。

IoC主要通过DI(Dependency Injection,依赖注入)实现,而DI在实现上主要是通过反射完成的,通过反射动态创建对象。

依赖注入的方式:

构造器注入

field注入(直接在定义的变量上注入)

property注入(通过field的setter方法来注入)

注:

Spring依赖注入可通过多种注解达到目的,区别:@Autowired、@Resource等用于引用对象的注入,@Value用于基本类型的的注入。

构造器注入比较容易引起一些问题(如循环依赖导致注入失败从而程序无法启动),实际场景中通常用field注入。

循环依赖问题可以通过setter延迟注入解决:循环依赖使得实例化Bean时因对彼此的依赖满足不了,从而实例化失败;通过延迟注入使得注入时Bean已经创建了,从而可注入成功。

IoC与DI的区别:

IoC表示对象的创建等生命周期由特定容器(如Spring容器)管理。"instantiating objects (beans)"

DI表示对象所依赖的其他“合作者”(其他对象)由容器负责注入到当前对象中。可能是创建对象时注入,也可能是用到依赖的对象时注入。"wiring up of collaborators (or dependencies)"

 

2 Spring IoC过程分析

三部分组成:

类定义:定义普通的POJO。

元数据定义:关于所要创建的Bean的一些元数据信息。定义方式有三种:xml、java注解、java代码。

创建和关联Bean:Spring容器将根据元数据信息及POJO创建出一系列Bean,并进行管理。

Spring IoC 原理

 

 

主要过程:

定位Bean元数据:可在classpath、filesystem、network等位置;Bean可通过XML(beans、bean元素等)、注解(Congifuration、Bean注解等)、Java代码三种方式定

加载Bean元数据:读入后创建成BeanDefinition

注册:根据BeanDefinition创建Bean对象并注册到IoC容器(即ApplicationContext)。注意并不是一定都立马创建实例,未被用到的会延迟到等被使用时再创建。

依赖注入:对Bean中依赖其他Bean实例的属性赋值(AbstractAutoWireCapableBeanFactory.populateBean)

 

Spring IoC容器(Bean Container)、ApplicationContext、BeanFactory可以理解为同一个东西:ApplicationContext和BeanFactory为对容器概念的实现,只不过前者为读容器内容,而后者可以读写容器内容。

BeanFactory体系:

Spring IoC 原理

 

 

Bean体系:Spring中Bean对象用BeanDefinition描述

Spring IoC 原理

BeanDefinition包含如下信息:

    • A package-qualified class name: typically, the actual implementation class of the bean being defined.

    • Bean behavioral configuration elements, which state how the bean should behave in the container (scope, lifecycle callbacks, and so forth).

    • References to other beans that are needed for the bean to do its work. These references are also called collaborators or dependencies.

    • Other configuration settings to set in the newly created object — for example, the size limit of the pool or the number of connections to use in a bean that manages a connection pool.

 

 BeanDefinition解析器:

Spring IoC 原理

 

 IoC容器体系:

Spring IoC 原理

 

 

3 Spring Core(IoC Container)doc阅记

官方文档链接:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html

目录:

Spring IoC 原理

 

3.1 Customizing the Nature of a Bean

顺序:

bean Instantiate:

BeanPostProcessor.postProcessBeforeInitialization

bean Initialize:

BeanPostProcessor.postProcessAfterInitialization

 

@PostConstruct

InitializingBean.afterPropertiesSet

@Bean[initMethod]

bean destroy:

@PreDestroy

DisposableBean.destroy

@Bean[destroyMethod]

 

主要用途:配置参数的解析(BeanFactoryPostProcessor)、参数或依赖的注入(BeanPostProcessor)、类或方法参数的validation(BeanPostProcessor)

 

3.1.1 LifeCycle Callback - Bean initialization/destroy callback

定义某个Bean创建完和销毁前的操作,三种方式:

在Bean内通过注解指定方法:@PostConstruct、@PreDestroy

Bean实现特定接口:InitializingBean.afterPropertiesSet、DisposableBean.destroy

通过@Bean属性指定方法:initMethod、destroyMethod

 The Spring container guarantees that a configured initialization callback is called immediately after a bean is supplied with all dependencies. Thus, the initialization callback is called on the raw bean reference, which means that AOP interceptors and so forth are not yet applied to the bean. A target bean is fully created first and then an AOP proxy (for example) with its interceptor chain is applied.

示例:

Spring IoC 原理
 1 @Configuration
 2 class CustomBeanLifecycle {
 3 
 4     @Bean(initMethod = "myInit", destroyMethod = "myDestroy")
 5     public AdminModel getAdminModel() {
 6         return new AdminModel();
 7     }
 8 
 9     // The Spring container guarantees that a configured initialization callback is
10     // called immediately after a bean is supplied with all dependencies. Thus, the
11     // initialization callback is called on the raw bean reference, which means that
12     // AOP interceptors and so forth are not yet applied to the bean.
13     public static class AdminModel implements InitializingBean, DisposableBean {
14         //
15         public void myInit() {
16             System.err.println(this + " @Bean[initMethod]");
17         }
18 
19         public void myDestroy() {
20             System.err.println(this + " @Bean[destroyMethod]");
21         }
22 
23         //
24         @Override
25         public void afterPropertiesSet() throws Exception {
26             System.err.println(this + " InitializingBean.afterPropertiesSet");
27         }
28 
29         @Override
30         public void destroy() throws Exception {
31             System.err.println(this + " DisposableBean.destroy");
32         }
33 
34         //
35         @PostConstruct
36         public void p1() {
37             System.err.println(this + " PostConstruct1");
38         }
39 
40         @PostConstruct
41         public void p2() {
42             System.err.println(this + " PostConstruct2");
43         }
44 
45         @PreDestroy
46         public void d1() {
47             System.err.println(this + " @PreDestroy1");
48         }
49 
50         @PreDestroy
51         public void d2() {
52             System.err.println(this + " @PreDestroy2");
53         }
54     }
55 }
56 
57 
58 
59 //启动时输出:
60 com.marchon.learn.store.config.CustomBeanLifecycle$AdminModel@264f18fe PostConstruct1
61 com.marchon.learn.store.config.CustomBeanLifecycle$AdminModel@264f18fe PostConstruct2
62 com.marchon.learn.store.config.CustomBeanLifecycle$AdminModel@264f18fe InitializingBean.afterPropertiesSet
63 com.marchon.learn.store.config.CustomBeanLifecycle$AdminModel@264f18fe @Bean[initMethod]
64 
65 //kill 9时输出
66 com.marchon.learn.store.config.CustomBeanLifecycle$AdminModel@264f18fe @PreDestroy1
67 com.marchon.learn.store.config.CustomBeanLifecycle$AdminModel@264f18fe @PreDestroy2
68 com.marchon.learn.store.config.CustomBeanLifecycle$AdminModel@264f18fe DisposableBean.destroy
69 com.marchon.learn.store.config.CustomBeanLifecycle$AdminModel@264f18fe @Bean[destroyMethod]
Initialization and Destroy callbacks

相关文章:

  • 2022-01-12
  • 2021-06-23
  • 2022-02-20
  • 2022-01-10
  • 2021-06-23
猜你喜欢
  • 2022-12-23
  • 2021-05-20
  • 2021-06-25
  • 2021-08-03
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案