当前位置: 首页 > news >正文

第7章 Spring中的Bean的管理

目录/Contents

  • 第7章 Spring中的Bean的管理
    • 学习目标
      • 了解Spring IoC容器的原理
      • 掌握Bean标签及其属性的使用
      • 熟悉Bean的实例化
      • 掌握Bean的作用域
      • 掌握Bean的装配方式
      • 熟悉Bean的生命周期
    • 学习内容
      • 1 Spring IoC容器
        • 1.1 BeanFactory接口
          • 1.1.1 BeanFactory接口的常用方法
          • 1.1.2 BeanFactory接口实例的语法格式
        • 1.2 ApplicationContext接口
          • 1.2.1 ApplicationContext接口的特点
          • 1.2.2 ApplicationContext接口的常用实现类
      • 2 Bean的配置
        • 2.1 Spring容器所支持的配置文件格式
        • 2.2 \<bean>元素的常用属性
        • 2.3 \<bean>元素的常用子元素
        • 2.4 普通的Bean通常只需定义id(或者name)和class两个属性
      • 3 Bean的实例化
        • 3.1 构造方法实例化
          • STEP 01
          • STEP 02
          • STEP 03
          • STEP 04
          • STEP 05
        • 3.2 静态工厂实例化
          • STEP 01
          • STEP 02
          • STEP 03
          • STEP 04
          • STEP 05
        • 3.3 实例工厂实例化
          • STEP 01
          • STEP 02
          • STEP 03
          • STEP 04
          • STEP 05
      • 4 Bean的作用域
        • 4.1 singleton作用域
        • 4.2 通过案例的方式演示Spring容器中singleton作用域的使用。
          • STEP 01
          • STEP 02
          • STEP 03
        • 4.3 prototype作用域
      • 5 Bean的装配方式
        • 5.1 基于XML的装配
          • 5.1.1 两种基于XML的装配方式
          • 5.1.2 a.属性setter方法注入
          • 5.1.3 b.构造方法注入
        • 5.2 基于注解的装配
          • 5.2.1 XML与注解装配的比较
          • 5.2.2 Spring的常用注解
          • 5.2.3 下面通过案例演示如何使用注解来装配Bean
          • STEP 01
          • STEP 02
          • STEP 03
          • STEP 04
          • STEP 05
          • STEP 06
          • STEP 07
          • STEP 08
          • STEP 09
          • STEP 10
        • 5.3 自动装配
        • 5.3.1 如何实现自动装配
        • 5.3.2 autowire属性的值
      • 6 Bean的生命周期
        • 6.1 Bean在不同作用域内的生命周期
        • 6.2 Bean生命周期的两个时间节点
        • 6.3 监控时间节点的方式
        • STEP 01
        • STEP 02
        • STEP 03
        • STEP 04

第7章 Spring中的Bean的管理

学习目标

了解Spring IoC容器的原理

掌握Bean标签及其属性的使用

熟悉Bean的实例化

掌握Bean的作用域

掌握Bean的装配方式

熟悉Bean的生命周期

学习内容

1 Spring IoC容器

1.1 BeanFactory接口

1.1.1 BeanFactory接口的常用方法

在这里插入图片描述

1.1.2 BeanFactory接口实例的语法格式

Spring提供了几个BeanFactory接口的实现类,其中最常用的是XmlBeanFactory,它可以读取XML文件并根据XML文件中的配置信息生成BeanFactory接口的实例,BeanFactory接口的实例用于管理Bean。XmlBeanFactory类读取XML文件生成BeanFactory接口实例的具体语法格式如下。

BeanFactory beanFactory=new XmlBeanFactory
	(new FileSystemResource(D:/bean.xml”));

1.2 ApplicationContext接口

1.2.1 ApplicationContext接口的特点

ApplicationContext接口建立在BeanFactory接口的基础之上,它丰富了BeanFactory接口的特性,例如,添加了对国际化、资源访问、事件传播等方面的支持。
ApplicationContext接口可以为单例的Bean实行预初始化,并根据<property>元素执行setter方法,单例的Bean可以直接使用,提升了程序获取Bean实例的性能。

1.2.2 ApplicationContext接口的常用实现类

在这里插入图片描述

2 Bean的配置

2.1 Spring容器所支持的配置文件格式

Spring容器支持XML和Properties两种格式的配置文件,在实际开发中,最常用的是XML格式的配置文件。XML是标准的数据传输和存储格式,方便查看和操作数据。在Spring中,XML配置文件的根元素是<beans>,<beans>元素包含<bean>子元素,每个<bean>子元素可以定义一个Bean,通过<bean>元素将Bean注册到Spring容器中。

2.2 <bean>元素的常用属性

在这里插入图片描述

2.3 <bean>元素的常用子元素

在这里插入图片描述

2.4 普通的Bean通常只需定义id(或者name)和class两个属性

<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
http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--使用id属性定义bean1,对应的实现类为com.itheima.Bean1-->
    <bean id="bean1" class="com.itheima.Bean1">
    </bean>
    <!--使用name属性定义bean2,对应的实现类为com.itheima.Bean2-->
    <bean name="bean2" class="com.itheima.Bean2"/>
</beans>

3 Bean的实例化

3.1 构造方法实例化

下面通过一个案例演示Spring容器如何通过构造方法实例化Bean。

STEP 01

在IDEA中创建一个名为chapter07的Maven项目,然后在项目的pom.xml文件中配置需使用到的Spring四个基础包和Spring的依赖包。

<!– 这里只展示了一个依赖包-->
<!-- spring-expression的依赖包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>5.2.8.RELEASE</version>
        </dependency>
STEP 02

创建一个名称为com.itheima的包,在该包中创建Bean1类。

package com.itheima;
public class Bean1 {
    public Bean1(){
        System.out.println("这是Bean1");
    }
}
STEP 03

新建applicationBean1.xml作为Bean1类的配置文件,在该配置文件中定义一个id为bean1的Bean,并通过class属性指定其对应的实现类为Bean1。

<?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
	http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="bean1" class="com.itheima.Bean1"></bean>
</beans>
STEP 04

创建测试类Bean1Test,在main()方法中通过加载applicationBean1.xml配置文件初始化Spring容器,再通过Spring容器生成Bean1类的实例bean1,用来测试构造方法是否能实例化Bean1。

public class Bean1Test {
    public static void main(String[] args){
        // 加载applicationBean1.xml配置
        ApplicationContext applicationContext=new 
                                             ClassPathXmlApplicationContext("applicationBean1.xml");
        // 通过容器获取配置中bean1的实例
        Bean1 bean=(Bean1) applicationContext.getBean("bean1");
        System.out.print(bean);		}
}
STEP 05

在IDEA中启动Bean1Test类,控制台会输出结果。

在这里插入图片描述

3.2 静态工厂实例化

下面通过一个案例演示如何使用静态工厂方式实例化Bean。

STEP 01

创建Bean2类,该类与Bean1类一样,只定义一个构造方法,不需额外添加任何方法。

package com.itheima;
public class Bean2 {
    public Bean2(){
        System.out.println("这是Bean2");
    }
}
STEP 02

创建一个MyBean2Factory类,在该类中定义一个静态方法createBean(),用于创建Bean的实例。createBean()方法返回Bean2实例。

package com.itheima;
public class MyBean2Factory {
	//使用MyBean2Factory类的工厂创建Bean2实例
    	public static Bean2 createBean(){
      	return new Bean2();
    	}
}
STEP 03

新建applicationBean2.xml文件,作为MyBean2Factory类的配置文件。

<?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
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
<bean id="bean2"
      class="com.itheima.MyBean2Factory"
      factory-method="createBean"/>
</beans>
STEP 04

创建一个测试类Bean2Test,用于测试使用静态工厂方式是否能实例化Bean。

public class Bean2Test {
    public static void main(String[] args) {
        // ApplicationContext在加载配置文件时,对Bean进行实例化
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationBean2.xml");
        System.out.println(applicationContext.getBean("bean2"));
    }
}
STEP 05

在IDEA中启动Bean2Test类,控制台会输出结果。

在这里插入图片描述

3.3 实例工厂实例化

下面通过一个案例演示如何使用实例工厂方式实例化Bean。

STEP 01

创建Bean3类,该类与Bean1一样,只需编写一个构造方法。

package com.itheima;
public class Bean3 {
    public Bean3(){
        System.out.println("这是Bean3");
    }
}
STEP 02

创建一个MyBean3Factory类,在该类中定义无参构造方法,并定义createBean()方法用于创建Bean3对象。

package com.itheima;
public class MyBean3Factory {
    public MyBean3Factory() {
        System.out.println("bean3工厂实例化中");
    }
    public Bean3 createBean() { //创建Bean3实例的方法
        return new Bean3();
    }
}
STEP 03

新建applicationBean3.xml文件,作为MyBean3Factory类的配置文件。

<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
    http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
    <!-- 配置工厂 -->
    <bean id="myBean3Factory”	class="com.itheima.MyBean3Factory" />
    <!-- 使用factory-bean属性指向配置的实例工厂-->
    <bean id="bean3" factory-bean="myBean3Factory"
          factory-method="createBean" />
</beans>
STEP 04

创建一个测试类BeanTest3,用于测试使用实例化工厂方式是否能实例化Bean。

public class Bean3Test {
    public static void main(String[] args) {
        // ApplicationContext在加载配置文件时,对Bean进行实例化
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationBean3.xml");
        System.out.println(applicationContext.getBean("bean3"));
    }
}
STEP 05

在IDEA中启动Bean3Test类,控制台会输出结果。

在这里插入图片描述

4 Bean的作用域

4.1 singleton作用域

Spring支持的5种作用域
在这里插入图片描述

4.2 通过案例的方式演示Spring容器中singleton作用域的使用。

STEP 01

将id为bean1的作用域设置为singleton。

<?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
	http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="bean1" class="com.itheima.Bean1" scope="singleton"></bean>
</beans>
STEP 02

创建测试类scopeTest,在main()方法中通过加载applicationBean1.xml配置文件初始化Spring容器,通过Spring容器获取Bean1类的两个实例,判断两个实例是否为同一个。

public class scopeTest{
    public static void main(String[] args){
        ApplicationContext applicationContext=new 
               ClassPathXmlApplicationContext("applicationBean1.xml");
        Bean1 bean1_1=(Bean1) applicationContext.getBean("bean1");
        Bean1 bean1_2=(Bean1) applicationContext.getBean("bean1");
        System.out.print(bean1_1==bean1_2);	}
}
STEP 03

在IDEA中启动scopeTest类,控制台会输出运行结果。
在这里插入图片描述

4.3 prototype作用域

prototype作用域的使用

<?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
	http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="bean1" class="com.itheima.Bean1" scope="prototype"></bean> 
</beans>

5 Bean的装配方式

5.1 基于XML的装配

5.1.1 两种基于XML的装配方式

在基于XML的装配就是读取XML配置文件中的信息完成依赖注入,Spring容器提供了两种基于XML的装配方式,属性setter方法注入和构造方法注入。下面分别对这两种装配方式进行介绍。

5.1.2 a.属性setter方法注入

属性setter方法注入要求一个Bean必须满足以下两点要求。
(1)Bean类必须提供一个默认的无参构造方法。
(2)Bean类必须为需要注入的属性提供对应的setter方法。

5.1.3 b.构造方法注入

使用构造方法注入时,在配置文件里,需要使用元素的子元素来定义构造方法的参数,例如,可以使用其value属性(或子元素)来设置该参数的值。

5.2 基于注解的装配

5.2.1 XML与注解装配的比较

在Spring中,使用XML配置文件可以实现Bean的装配工作,但在实际开发中如果Bean的数量较多,会导致XML配置文件过于臃肿,给后期维护和升级带来一定的困难。为解决此问题,Spring提供了注解,通过注解也可以实现Bean的装配。

5.2.2 Spring的常用注解

在这里插入图片描述
在这里插入图片描述

5.2.3 下面通过案例演示如何使用注解来装配Bean
STEP 01

导入依赖:在项目chapter07的pom.xml文件中导入spring-aop-5.2.8.RELEASE.jar依赖包,导入代码如下所示。

<dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-aop</artifactId>
          <version>5.2.8.RELEASE</version>
 </dependency>
STEP 02

XML配置文件:创建applicationContext.xml,在该文件中引入Context约束并启动Bean的自动扫描功能。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="com.itheima" />
</beans>
STEP 03

定义实体类:新建entity包,在entity包下创建User实体类。

@Component("user")
@Scope("singleton")
public class User {
    @Value("1")
    private int id;
    @Value("张三")
    private String name;
    @Value("123")
    private String password;
    // 省略getter/setter方法和toString()方法
}
STEP 04

定义dao层:创建UserDao接口作为数据访问层接口,并在UserDao接口中声明save()方法,用于查询User实体的对象信息。

package com.itheima.dao;
public interface UserDao {
    public void save();
}
STEP 05

实现dao层:
创建UserDaoImpl作为UserDao的实现类,并在UserDaoImpl类中实现UserDao接口中的save()方法。

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    public void save(){
        ApplicationContext applicationContext=new 
              ClassPathXmlApplicationContext("applicationContext.xml");
        User user=(User) applicationContext.getBean("user");
        System.out.println(user);
        System.out.println("执行UserDaoImpl.save()");
    }
}
STEP 06

定义service层:创建UserService接口作为业务逻辑层接口,并在UserService接口中定义save()方法。

package com.itheima.service;
public interface UserService {
    public void save();
}
STEP 07

实现service层:创建UserServiceImpl作为UserService的实现类,并在UserServiceImpl类中实现UserService接口中的save()方法。

@Service("userService")
public class UserServiceImpl implements UserService {
        //使用@Resource注解注入UserDao
        @Resource(name="userDao")
        private UserDao userDao;
        public void save(){
            this.userDao.save();
            System.out.println("执行UserServiceImpl.save()");
        }
}
STEP 08

定义controller层: 创建UserController类作为控制层。

@Controller
public class UserController {
    //使用@Resource注解注入UserService
    @Resource(name="userService")
    private UserService userService;
    public void save(){
        this.userService.save();
        System.out.println("执行UserController.save()");
    }
}
STEP 09

定义测试类:创建测试类AnnotationTest,在该类中编写测试代码,通过Spring容器加载配置文件并获取UserController实例,然后调用实例中的save()方法。

public class AnnotationTest {
    public static void main(String[] args){
        ApplicationContext applicationContext=new 
             ClassPathXmlApplicationContext("applicationContext.xml");
        UserController usercontroller=(UserController) 
             applicationContext.getBean("userController");
        usercontroller.save();
    }
}
STEP 10

查看运行结果:在IDEA中启动AnnotationTest类,控制台会输出结果。

在这里插入图片描述

5.3 自动装配

5.3.1 如何实现自动装配

Spring的元素中包含一个autowire属性,可以通过设置autowire属性的值实现Bean的自动装配。

5.3.2 autowire属性的值

在这里插入图片描述

6 Bean的生命周期

6.1 Bean在不同作用域内的生命周期

Bean的生命周期是指Bean实例被创建、初始化和销毁的过程。在Bean的两种作用域singleton和prototype中,Spring容器对Bean的生命周期的管理是不同的。在singleton作用域中,Spring容器可以管理Bean的生命周期,控制着Bean的创建、初始化和销毁。在prototype作用域中,
Spring容器只负责创建Bean实例,不会管理其生命周期。

6.2 Bean生命周期的两个时间节点

在Bean的生命周期中,有两个时间节点尤为重要,这两个时间节点分别是Bean实例初始化后和Bean实例销毁前,在这两个时间节点通常需要完成一些指定操作。因此,常常需要对这两个节点进行监控。

6.3 监控时间节点的方式

监控两个节点的方式有两种,一种是使用XML配置文件,一种是使用注解。
Spring容器提供了@PostConstruct用于监控Bean对象初始化节点, 提供了@PreDestroy用于监控Bean对象销毁节点。
下面通过案例演示这两个注解的使用。

STEP 01

创建Student类,在类中定义id和name字段,并使用@PostConstruct指定初始化方法,使用@PreDestroy指定Bean销毁前的方法。

@Component("student")
public class Student {
    @Value("1")
    private String id;
    @Value("张三")
    private String name; 	// 省略getter/setter方法,以及toString()方法
    @PostConstruct
    public void init(){System.out.println("Bean的初始化完成,调用init()方法");	}
    @PreDestroy
    public void destroy(){System.out.println("Bean销毁前调用destroy()方法");		}}

STEP 02

创建applicationStudent.xml,在该文件中引入Context约束并启动Bean的自动扫描功能。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 使用context命名空间,在配置文件中开启相应的注解处理器 -->
    <context:component-scan base-package="com.itheima" />
</beans>

STEP 03

创建测试类StudentTest,在该类中编写测试代码,通过Spring容器加载配置文件并获取Student实例。

public class StudentTest {
    public static void main(String[] args){
    ApplicationContext applicationContext=new 
            ClassPathXmlApplicationContext("applicationStudent.xml");
    Student student=(Student)applicationContext.getBean("student");
    System.out.println(student);
    //销毁Spring容器中的所有Bean
    AbstractApplicationContext ac=(AbstractApplicationContext)
            applicationContext;
    ac.registerShutdownHook();
}}

STEP 04

在IDEA中启动StudentTest类,控制台会输出结果。

在这里插入图片描述

相关文章:

  • 计算机组成原理_存储系统结构
  • 3D建模|手绘角色模型和手绘场景模型有什么区别?
  • 中成药数据图谱可视化与知识问答平台研究
  • Eclipse配置作者信息
  • Arrays.asList和ArrayList.subList
  • MySQL架构优化
  • python从入门到实践:软件开发目录规范
  • vue3新拟态组件库开发流程——loading组件源码
  • JS中新逻辑赋值运算符使用(?.、? ?、| |=、=)
  • 软考网络工程师需要哪些复习资料?
  • CIPT备考心得分享-下一个考过的就是你
  • 构建集团统一管控体系,低代码派上用场
  • iconfont 使用
  • 4.类的定义,变量类型,方法类型
  • pytorch中一些有关tensor的操作
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 2017前端实习生面试总结
  • extjs4学习之配置
  • isset在php5.6-和php7.0+的一些差异
  • MobX
  • Mybatis初体验
  • Rancher-k8s加速安装文档
  • Sequelize 中文文档 v4 - Getting started - 入门
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • 动态规划入门(以爬楼梯为例)
  • 解析 Webpack中import、require、按需加载的执行过程
  • 使用前端开发工具包WijmoJS - 创建自定义DropDownTree控件(包含源代码)
  • 线上 python http server profile 实践
  • 一文看透浏览器架构
  • (多级缓存)多级缓存
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (数据结构)顺序表的定义
  • (四) Graphivz 颜色选择
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (转)德国人的记事本
  • (转)视频码率,帧率和分辨率的联系与区别
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .NET Core/Framework 创建委托以大幅度提高反射调用的性能
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .net on S60 ---- Net60 1.1发布 支持VS2008以及新的特性
  • .NET单元测试
  • .Net中ListT 泛型转成DataTable、DataSet
  • ::before和::after 常见的用法
  • @PreAuthorize注解
  • @RestControllerAdvice异常统一处理类失效原因
  • [ vulhub漏洞复现篇 ] Grafana任意文件读取漏洞CVE-2021-43798
  • [2021 蓝帽杯] One Pointer PHP
  • [Android]使用Retrofit进行网络请求
  • [Angular] 笔记 21:@ViewChild
  • [Angularjs]asp.net mvc+angularjs+web api单页应用之CRUD操作
  • [AutoSAR 存储] 汽车智能座舱的存储需求
  • [AX]AX2012 AIF(四):文档服务应用实例