Spring之IoC

news/2025/1/15 23:02:43/

文章目录

    • 一.SpringIoC核心概念
      • 1.IOC(Inversion of Control)控制反转
      • 2.DI(Dependency Injection)依赖注入
    • 二.bean的实例化
      • 1.构造方法实例化bean
      • 2.静态工厂方法实例化bean
    • 三.Bean的生命周期
      • 1.Bean的实例化
      • 2.设置属性
      • 3.Bean初始化
      • 4.bean的使用和销毁

一.SpringIoC核心概念

IOC、IOC容器、Bean、DI

1.IOC(Inversion of Control)控制反转

  1. 什么是控制翻转?

当我们需要使用对象的时候,我们一般会new来产生对象,但使用IoC思想后,我们获取对象不再是主动new对象,而是将该对象的创建控制权交给‘外部’,由‘外部’创建对象并交给我们。

  1. Spring和IoC之间的关系是什么?

IoC是一种思想,Spring对IoC进行了实现
Spring提供一个容器,名为IoC容器,充当IoC容器中的‘外部’

  1. IoC容器的作用是什么?

IoC容器存放了一个个的bean对象
IoC容器负责对象的创建,初始化等一系列工作

2.DI(Dependency Injection)依赖注入

  1. 什么是依赖注入?

容器中建立bean与bean之间的依赖关系的整个过程,就叫做依赖注入

总结:DI可以认为是IoC的一种具体实现

二.bean的实例化

对象已经能交给Spring的IOC容器来创建了,但是容器是如何来创建对象的呢?这就需要了解bean的实例化过程了

实例化bean可以通过配置文件来实现,但过于繁琐,下面所有内容将尽量使用注解来完成

1.构造方法实例化bean

顾名思义,bean其实就是一个对象,对象实例化自然就会调用自己的构造函数

使用@Componet注解

@Component("bookDao")
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ..." );}
}

之前没使用注解的时候,需要手动在配置文件中配置,使用完注解后,只需要配置spring的扫描包路径,就会达到和在配置文件中定义bean一样的效果

注意:Spring底层使用的是无参构造函数来实例化bean的。

2.静态工厂方法实例化bean

首先,我们需要创建一个配置类,并在这个类上添加@Configuration注解:

@Configuration  
public class AppConfig {  // ...  
}

然后,在这个配置类中添加一个工厂方法,并在这个方法上添加@Bean注解:

@Configuration  
public class AppConfig {  @Bean  public MyBean myBean() {  return new MyBean();  }  // ...  
}

静态的工厂方法

public class MyBeanFactory {  public static MyBean createMyBean() {  // 创建并返回MyBean实例的代码  }  
}

最后

@Configuration  
public class AppConfig {  @Bean  public MyBean myBean() {  return MyBeanFactory.createMyBean();  }  // ...  
}

三.Bean的生命周期

Bean的生命周期注意可以分为五个部分:1.Bean的实例化,2.设置属性,3.Bean的初始化方法,4.使用,5.销毁

1.Bean的实例化

上文已经讲述不再赘述了

2.设置属性

依赖注入指的是建立bean与bean之间的依赖关系,设置属性有三种方式:1.属性注入(Autowire),2.setter注入,3.构造器注入

属性注入

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Component;  @Component  
public class MyClass {  @Autowired(required = false)  private MyDependency myDependency;  // ... 其他代码 ...  
}

setter注入

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Component;  @Component  
public class MyClass {  private MyDependency myDependency;  @Autowired  public void setMyDependency(MyDependency myDependency) {  this.myDependency = myDependency;  }  // ... 其他代码 ...  
}

构造器注入

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.stereotype.Component;  @Component  
public class MyClass {  private MyDependency myDependency;  @Autowired  public MyClass(MyDependency myDependency) {  this.myDependency = myDependency;  }  // ... 其他代码 ...  
}

总结:实例化和初始化的区别

实例化和属性设置是 Java 级别的系统“事件”,其操作过程不可⼈⼯⼲预和修改;⽽初始化是给开发者
提供的,可以在实例化之后,类加载完成之前进⾏⾃定义“事件”处理。

3.Bean初始化

1.实现了各种 Aware 通知的⽅法,如 BeanNameAware、BeanFactoryAwared,ApplicationContextAware
例如:

public class MyBeanFactory implements BeanFactoryAware {private BeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}public void getMyBeanName() {MyBeanName myBeanName = beanFactory.getBean(MyBeanName.class);System.out.println(beanFactory.isSingleton("myCustomBeanName"));}
}

通过beanFactory我们就可以手动获取IoC容器中的bean了

ApplicationContextAware 的接⼝⽅法

@Component
public class ApplicationContextUtil implements ApplicationContextAware {private static ApplicationContext context;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {context = applicationContext;}public static ApplicationContext getApplicationContext(){return context;}}

作用和BeanFactoryAware接口类似,都是获取spring上下文
2.执⾏ BeanPostProcessor 初始化前置⽅法

public class MyBeanPostProcessor implements BeanPostProcessor{/*** 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务* 注意:方法返回值不能为null* 如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象* 因为后置处理器从Spring IoC容器中取出bean实例对象没有再次放回IoC容器中*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("初始化 before--实例化的bean对象:"+bean+"\t"+beanName);// 可以根据beanName不同执行不同的处理操作return bean;
}/*** 实例化、依赖注入、初始化完毕时执行 * 注意:方法返回值不能为null* 如果返回null那么在后续初始化方法将报空指针异常或者通过getBean()方法获取不到bena实例对象* 因为后置处理器从Spring IoC容器中取出bean实例对象没有再次放回IoC容器中*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("初始化 after...实例化的bean对象:"+bean+"\t"+beanName);// 可以根据beanName不同执行不同的处理操作return bean;
}}

BeanPostProcessor主要作用于初始化方法执行前后

3.执⾏ @PostConstruct 初始化⽅法,依赖注⼊操作之后被执⾏;
4.执⾏⾃⼰指定的 init-method ⽅法(如果有指定的话);
在这里插入图片描述
5.执⾏ BeanPostProcessor 初始化后置⽅法。

见上述第二条

4.bean的使用和销毁

使用不用多说,bean销毁前也会执行一些销毁方法

销毁容器的各种⽅法,如 @PreDestroy、DisposableBean 接⼝⽅法、destroy-method。
@PreDestroy==DisposableBean

@Component
public class MyBean implements DisposableBean {// ...@Overridepublic void destroy() throws Exception {// 执行清理操作System.out.println("MyBean销毁前执行清理操作");}
}

以上就是我对SpringIoC容器的见解,如有错误望指正!


http://www.ppmy.cn/news/1133504.html

相关文章

第四十一章 持久对象和SQL - Storage

文章目录 第四十一章 持久对象和SQL - StorageStorage存储定义概览持久类使用的Globals注意 第四十一章 持久对象和SQL - Storage Storage 每个持久类定义都包含描述类属性如何映射到实际存储它们的Global的信息。类编译器为类生成此信息,并在修改和重新编译时更新…

OSI体系结构和TCP/IP体系结构

在第一章( 计网第一章 )的时候,曾经提到过OSI体系结构和TCP/IP体系结构,并对它们进行了简单的对比。这篇博客在其基础上进行更深层次的理解。 一.OSI体系结构: 通信子网: 计算机网络在逻辑功能上可以分为…

【Java 进阶篇】MySQL数据库范式详解

范式是数据库设计中的一种理论方法,旨在通过减少数据冗余来提高数据存储的有效性和完整性。在MySQL数据库中,范式设计是一个重要的概念,它有助于组织和管理数据,确保数据的一致性和可靠性。本文将深入探讨数据库范式,包…

【OpenMV】形状识别 特征点检测 算法的组合使用

目录 形状识别 圆形检测 矩形识别 特征点检测 算法的组合使用 形状识别 圆形 霍夫圆检测算法 通过霍夫变换查找圆,支持openmv3以上 矩形 四元检测算法 识别任意大小任意角度的矩形,四元检测算法对图像的失真,畸变没有要求,畸…

[React] React高阶组件(HOC)

文章目录 1.Hoc介绍2.几种包装强化组件的方式2.1 mixin模式2.2 extends继承模式2.3 HOC模式2.4 自定义hooks模式 3.高阶组件产生初衷4.高阶组件使用和编写结构4.1 装饰器模式和函数包裹模式4.2 嵌套HOC 5.两种不同的高阶组件5.1 正向的属性代理5.2 反向的继承 6.如何编写高阶组…

Java环境配置无效

Java环境配置无效 老是使用1.8版本,象牛皮癣。 查找java来源 where java 打开C:\Windows\System32 删掉java.exe javaaw.exe javaaws.exe 正常

阅读LINGO-1: Exploring Natural Language for Autonomous Driving

1 背景2 Motivation3 具体过程 1 背景 wayve在9月14日公布了大语言模型和自动驾驶的结合模型LINGO-1,可以用自然语言解释自动驾驶的决策原因。 网页链接:https://wayve.ai/thinking/lingo-natural-language-autonomous-driving/ 但是目前没有论文和开源…

WIFI频段

问题: 5ghzwifi频段带宽怎么选 智造喵回答: 选择5GHz WiFi频段的带宽取决于你的网络需求和设备兼容性。通常有两种可选的带宽:20MHz和40MHz。 20MHz带宽:这是较为常见的 WiFi 频段带宽设置。它提供较好的穿墙能力和信号稳定性…