欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring概述 IOC容器和bean的配置

程序员文章站 2022-06-21 13:53:24
Spring学习(一)Spring概述 IOC容器和bean的配置1、Spring概述1.1、什么是Spring?Spring 是一个开源框架.Spring 为简化企业级应用开发而生. 使用 Spring 可以使简单的 JavaBean 实现以前只有 EJB 才能实现的功能.Spring 是一个 IOC(DI) 和 AOP 容器框架.Spring优良的特性轻量:Spring 是非侵入性的 基于Spring开发的应用中的对象可以不依赖于Spring的API依赖注入:DI—...

1、Spring概述

1.1、什么是Spring?

  • Spring 是一个开源框架.

  • Spring 为简化企业级应用开发而生. 使用 Spring 可以使简单的 JavaBean 实现以前只有 EJB 才能实现的功能.

  • Spring 是一个 IOC(DI) 和 AOP 容器框架.

  • Spring优良的特性

    1. 轻量Spring 是非侵入性的 基于Spring开发的应用中的对象可以不依赖于Spring的API
    2. 依赖注入:DI——Dependency Injection,反转控制(IOC)最经典的实现。
    3. 面向切面编程:Aspect Oriented Programming——AOP
    4. 容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期
    5. 框架:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。
    6. 一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)。
  • Spring模块

Spring概述  IOC容器和bean的配置

1.2、Spring的第一个HelloWorld程序

这里是用maven建的项目导入Spring相关的依赖 maven帮我们自动下载(若不是用maven建的则自己导入Spring相关的jar包)

<dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.6.RELEASE</version> </dependency> </dependencies>

创建一个User实体类

public class User { private String name; public User() { } public User(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void show(){ System.out.println("我的名字叫:"+name); } @Override public String toString() { return "User{" + "name='" + name + '\'' + '}'; } }

注意每次写这种实体类时 最好把无参构造方法写上

Spring配置文件applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 使用bean元素定义一个由IOC容器创建的对象 --> <!--id:指定用于引用bean实例的标识--> <!--class:指定用于创建bean的全类名 --> <bean id="User" class="com.song.pojo.User"> <property name="name" value="王五"></property> </bean> </beans>

测试

 public static void main(String[] args) { //创建IOC容器对象 ApplicationContext Context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); //根据id值获取bean实例对象 User user = (User) Context.getBean("User"); user.show(); }

2、IOC容器和Bean配置

2.1、IOC和DI

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

    其思想是反转资源获取的方向. 传统的资源查找方式要求组件向容器发起请求查找资源. 作为回应, 容器适时的返回资源. 而应用了 IOC 之后, 则是容器主动地将资源推送给它所管理的组件, 组件所要做的仅是选择一种合适的方式来接受资源. 这种行为也被称为查找的被动形式

  2. DI(Dependency Injection):依赖注入

    IOC 的另一种表述方式:即组件以一些预先定义好的方式(例如: setter 方法)接受来自如容器的资源注入.相对于 IOC 而言,这种表述更直接

2.2、在 Spring 的 IOC 容器里配置 Bean

  • Spring IOC 容器读取 Bean 配置创建 Bean 实例之前, 必须对它进行实例化. 只有在容器实例化后, 才可以从 IOC 容器里获取 Bean 实例并使用.
  • Spring 提供了两种类型的 IOC 容器实现.

BeanFactory: IOC 容器的基本实现.

ApplicationContext: 提供了更多的高级特性. 是 BeanFactory 的子接口.

–BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身;ApplicationContext 面向使用 Spring 框架的开发者,几乎所有的 应用场合都直接使用 ApplicationContext 而非底层的 BeanFactory

–无论使用何种方式, 配置文件时相同的.

2.2.1、ApplicationContext

  • ApplicationContext 的主要实现类:

    ClassPathXmlApplicationContext:从 类路径下加载配置文件

    –FileSystemXmlApplicationContext: 从文件系统中加载配置文件

  • ConfigurableApplicationContext 扩展于 ApplicationContext,新增加两个主要方法:refresh() 和 close(), 让 ApplicationContext 具有启动、刷新和关闭上下文的能力

  • ApplicationContext 在初始化上下文时就实例化所有单例的 Bean

  • WebApplicationContext 是专门为 WEB 应用而准备的,它允许从相对于 WEB 根目录的路径中完成初始化工作

2.2.1、环境搭配置测试

建一个学生基本信息实体类

public class Student { private String name;//姓名 private Integer age;//年龄 private String books[];//上课的书籍 一个数组 private CourseTeacher courseTeacher; //每门课老师的姓名 private List<String> hobbys;//爱好 private Map<String,String> card;//每个学生的所在地邮政编号 private Set<String> games;//喜欢的游戏 private String girlfriend;//是否有女朋友 private Properties info; public String getName() { return name; } //等下用来测试构造方法注入的 public Student(String name) { this.name = name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String[] getBooks() { return books; } public void setBooks(String[] books) { this.books = books; } public CourseTeacher getCourseTeacher() { return courseTeacher; } public void setCourseTeacher(CourseTeacher courseTeacher) { this.courseTeacher = courseTeacher; } public List<String> getHobbys() { return hobbys; } public void setHobbys(List<String> hobbys) { this.hobbys = hobbys; } public Map<String, String> getCard() { return card; } public void setCard(Map<String, String> card) { this.card = card; } public Set<String> getGames() { return games; } public void setGames(Set<String> games) { this.games = games; } public String getGirlfriend() { return girlfriend; } public void setGirlfriend(String girlfriend) { this.girlfriend = girlfriend; } public Properties getInfo() { return info; } public void setInfo(Properties info) { this.info = info; } public Student() { } //若写courseTeacher.toString()则要把CourseTeacher中属性值写上 不然会出现空指针异常 @Override public String toString() { return "Student{" + "姓名='" + name + '\'' + ", 年龄=" + age + ", books=" + Arrays.toString(books) + ", courseTeacher=" + courseTeacher + ", 爱好=" + hobbys + ", card=" + card + ", games=" + games + ", girlfriend='" + girlfriend + '\'' + ", info=" + info + '}'; } }
//每门课程老师的名字 public class CourseTeacher { private String math; private String chinese; private String english; public CourseTeacher() { } public CourseTeacher(String math, String chinese, String english) { this.math = math; this.chinese = chinese; this.english = english; } public String getMath() { return math; } public void setMath(String math) { this.math = math; } public String getChinese() { return chinese; } public void setChinese(String chinese) { this.chinese = chinese; } public String getEnglish() { return english; } public void setEnglish(String english) { this.english = english; } @Override public String toString() { return "CourseTeacher{" + "math='" + math + '\'' + ", chinese='" + chinese + '\'' + ", english='" + english + '\'' + '}'; } }

基本注入

<!--常量注入--> <bean id="User" class="com.song.pojo.User"> <property name="name" value="李四"></property> </bean>

测试

 @Test public void test01(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = (User) context.getBean("User"); System.out.println(user); }

引用其它 Bean注入

 <!--引用其他bean 使用ref--> <bean id="CourseTeacher" class="com.song.pojo.CourseTeacher"> <property name="chinese" value="语文老师"></property> <property name="math" value="数学老师"></property> <property name="english" value="英语老师"></property> </bean> <bean id="student2" class="com.song.pojo.Student"> <property name="name" value="小黄"></property> <property name="courseTeacher" ref="CourseTeacher"></property> </bean>

测试

 @Test public void test02(){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Student student = (Student) context.getBean("student2"); System.out.println(student); }

数组注入

 <!--数组注入--> <bean id="student3" class="com.song.pojo.Student"> <property name="books"> <array> <value>Java入门到精通</value> <value>go入门到精通</value> <value>C++入门到精通</value> <value>数据结构与算法</value> </array> </property> </bean>

List注入

<!--List注入--> <bean id="student4" class="com.song.pojo.Student"> <property name="hobbys"> <list> <value>打篮球</value> <value>看动漫</value> <value>听歌</value> </list> </property> </bean>

map注入

<!--Map注入--> <bean id="student5" class="com.song.pojo.Student"> <property name="card"> <map> <entry key="广州" value="1334"></entry> <entry key="湖北" value="43346"></entry> </map> </property> </bean>

set注入

<bean id="student6" class="com.song.pojo.Student"> <property name="games"> <set> <value>王者荣耀</value> <value>CF</value> <value>吃鸡</value> </set> </property> </bean>

null注入

<property name="girlfriend"><null/></property>

Propertise注入

<bean id="student7" class="com.song.pojo.Student"> <property name="info"> <props> <prop key="学号">20190604</prop> <prop key="系别">信息工程系</prop> <prop key="专业">软件工程</prop> </props> </property> </bean>

构造方法注入

 <bean id="student7" class="com.song.pojo.Student"> <constructor-arg index="0" value="小张" ></constructor-arg> </bean>

索引值指定参数位置

综合使用

<bean id="student8" class="com.song.pojo.Student"> <constructor-arg value="小张" index="0"></constructor-arg> <property name="age" value="18"></property> <property name="books"> <array> <value>Java入门到精通</value> <value>go入门到精通</value> <value>C++入门到精通</value> <value>数据结构与算法</value> </array> </property> <property name="courseTeacher" ref="CourseTeacher"></property> <property name="hobbys"> <list> <value>打篮球</value> <value>看动漫</value> <value>听歌</value> </list> </property> <property name="card"> <map> <entry key="广州" value="1334"></entry> <entry key="湖北" value="43346"></entry> </map> </property> <property name="games"> <set> <value>王者荣耀</value> <value>CF</value> <value>吃鸡</value> </set> </property> <property name="info"> <props> <prop key="学号">20190604</prop> <prop key="系别">信息工程系</prop> <prop key="专业">软件工程</prop> </props> </property> <property name="girlfriend"><null/></property> </bean>
//测试结果
Student{
   姓名='小张', 
   年龄=18, 
   books=[Java入门到精通, go入门到精通, C++入门到精通, 数据结构与算法], 
   courseTeacher=CourseTeacher{math='数学老师', chinese='语文老师', english='英语老师'},
   爱好=[打篮球, 看动漫, 听歌], 
   card={广州=1334, 湖北=43346}, 
   games=[王者荣耀, CF, 吃鸡], 
   girlfriend='null', 
   info={学号=20190604, 专业=软件工程, 系别=信息工程系}
   } 

还有一种工厂方法注入 用得少

2.3、bean的高级配置

  1. 配置信息的继承

  2. 配置信息的继承

    Spring允许继承bean的配置,被继承的bean称为父bean。继承这个父bean的bean称为子bean

    子bean从父bean中继承配置,包括bean的属性配置

    子bean也可以覆盖从父bean继承过来的配置

  3. 父bean可以作为配置模板,也可以作为bean实例。若只想把父bean作为模板,可以设置的abstract 属性为true,这样Spring将不会实例化这个bean

    如果一个bean的class属性没有指定,则必须是抽象bean

    并不是元素里的所有属性都会被继承。比如:autowire,abstract等。

    也可以忽略父bean的class属性,让子bean指定自己的类,而共享相同的属性配置。但此时abstract必须设为true

2.3.1、bean之间的依赖

有的时候创建一个bean的时候需要保证另外一个bean也被创建,这时我们称前面的bean对后面的bean有依赖

依赖关系不等于引用关系

2.3.2、bean的作用域

在Spring中,可以在元素的scope属性里设置bean的作用域,以决定这个bean是单实例的还是多实例的。

默认情况下,Spring只为每个在IOC容器里声明的bean创建唯一一个实例,整个IOC容器范围内都能共享该实例:所有后续的getBean()调用和bean引用都将返回这个唯一的bean实例。该作用域被称为singleton,它是所有bean的默认作用域。
Spring概述  IOC容器和bean的配置

当bean的作用域为单例时,Spring会在IOC容器对象创建时就创建bean的对象实例。而当bean的作用域为prototype时,IOC容器在获取bean的实例时创建bean的实例对象。

2.3.3、bean的生命周期

  1. Spring IOC容器可以管理bean的生命周期,Spring允许在bean生命周期内特定的时间点执行指定的任务。

  2. Spring IOC容器对bean的生命周期进行管理的过程:

  3. 在配置bean时,通过init-method和destroy-method 属性为bean指定初始化和销毁方法

    • 通过构造器或工厂方法创建bean实例
    • 为bean的属性设置值和对其他bean的引用
    • 调用bean的初始化方法
    • bean可以使用了
    • 当容器关闭时,调用bean的销毁方法
  4. bean的后置处理器

    • bean后置处理器允许在调用初始化方法前后对bean进行额外的处理
    • bean后置处理器对IOC容器里的所有bean实例逐一处理,而非单一实例。其典型应用是:检查bean属性的正确性或根据特定的标准更改bean的属性。
    • bean后置处理器时需要实现接口:org.springframework.beans.factory.config.BeanPostProcessor。在初始化方法被调用前后,Spring将把每个bean实例分别传递给上述接口的以下两个方法:
      • postProcessBeforeInitialization(Object, String)
      • postProcessAfterInitialization(Object, String)

    5.添加bean后置处理器后bean的生命周期

  • 通过构造器或工厂方法**创建****bean实例
  • 为bean的属性设置值和对其他bean的引用
  • 将bean实例传递给bean后置处理器的postProcessBeforeInitialization()方法
  • 调用bean的初始化方法
  • 将bean实例传递给bean后置处理器的postProcessAfterInitialization()**方法
  • bean可以使用了
  • 当容器关闭时调用bean的销毁方法

若想了解更多的Spring建议查看 Spring官网

Spring下载地址

本文地址:https://blog.csdn.net/qq_44763720/article/details/107678073

相关标签: IOC