spring基于XML方式的组件管理

基本介绍

依赖注入是一种处理对象间依赖关系的技术。在Spring中,依赖注入有构造方法注入和设值注入两种方式。

  • 设值注入是将依赖作为成员变量,通过主调类的setter方法注入依赖。
  • 构造方法注入则是在Bean的构造方法中注入依赖。

本次我们将通过具体例子来讲解这两种方式。

果汁店(juiceMaker)通过顾客的信息单(List)来生产饮品。

caseA - 取餐号001 ,橙汁,少糖,大杯

caseB- 取餐号002 ,贡茶,无糖,中杯


目录


一、环境准备

1.1,maven配置

 <dependencies>
        <!--spring context依赖-->
        <!--当你引入Spring Context依赖之后,表示将Spring的基础依赖引入了-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.6</version>
        </dependency>
        <!--junit5测试-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.3.1</version>
        </dependency>
    </dependencies>

二、构造方法注入

IoC容器在实例化Bean的过程中,会根据Bean的定义中的属性,查找并注入依赖。如果Bean定义中指定了构造函数,IoC容器会调用该构造函数,并将需要的依赖作为参数传递给该构造函数

2.1,基本组件类------ListA

1,此类的属性,fruit_sort,fruit_sugar,fruit_size。

2,toString方法方便测试。

3,构造方法ListA,上的@ConstructorProperties在测试中解释。

package com.zjr.list;

import java.beans.ConstructorProperties;

/**
 *  果汁的信息单
 */
public class ListA {
    private String fruit_sort;
    private String fruit_sugar;
    private String fruit_size;

    @Override
    public String toString() {
        return "ListA{" +
                "fruit_sort='" + fruit_sort + '\'' +
                ", fruit_sugar='" + fruit_sugar + '\'' +
                ", fruit_size='" + fruit_size + '\'' +
                '}';
    }
    @ConstructorProperties({"fruit_sort","fruit_sugar","fruit_size"})
    public ListA(String fruit_sort, String fruit_sugar, String fruit_size){
        this.fruit_sort = fruit_sort;
        this.fruit_sugar = fruit_sugar;
        this.fruit_size = fruit_size;
    }

}

2.2,基本组件类------MakerA

1,doWork方便测试

2,构造函数MakerA

package com.zjr.juiceMaker;

import com.zjr.list.ListA;

/**
 * 基于构造函数的依赖注入
 */
public class MakerA {
    private ListA listA;

    public String customNumber;

    public MakerA(ListA listA,String customNumber){
        this.listA = listA;
        this.customNumber = customNumber;
    }
    public void doWork(){
        System.out.println("请"+customNumber+"号顾客取餐 --"+listA.toString());
    }
}

2.3,XML配置

  • id:这是Bean的唯一标识符,当你在其他地方引用这个Bean时,你会使用这个ID。

  • class:定义Bean的类型,这是完全限定名,包括包名和类名。

  • constructor-arg:当Bean是通过构造函数注入时,你可以使用constructor-arg来指定构造函数参数的值或引用其Bean。其中index: 参数在构造函数参数列表中的位置索引。type: 参数类型。name: 参数名称。

  • ref:这是对其他Bean的引用,它允许你引用已经在IoC容器中定义的其他Bean(无需被引用的bean先定义,因为spring会先把所有的bean定义,后进行依赖注入)。

  • value:用于直接指定一个值,这个值会被赋给相应的属性或构造函数参数。

    <?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">

      <!--声明listA为bean-->
      <bean id="listA" class="com.zjr.list.ListA">
          <constructor-arg name="fruit_sort" value="橙汁"></constructor-arg>
          <constructor-arg name="fruit_sugar" value="少糖"></constructor-arg>
          <constructor-arg name="fruit_size" value="小杯"></constructor-arg>
      </bean>
      <!--声明MakerA为bean-->
      <bean id="makerA" class="com.zjr.juiceMaker.MakerA">
          <constructor-arg name="listA" ref="listA"></constructor-arg>
          <constructor-arg name="customNumber" value="001"></constructor-arg>
      </bean>
    
    </beans>

2.4,测试

在maven工程的测试类中新建一个测试类,写入测试方法如下代码。以下代码采用IOC接口ApplicationContext,实现方法是ClassPathXmlApplicationContext。

import com.zjr.juiceMaker.MakerA;
import com.zjr.juiceMaker.MakerB;
import com.zjr.list.ListA;
import com.zjr.list.ListB;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test_makerA {
    /**
     * 测试由JuiceA.xml配置的bean是否可以正常使用
     * 使用IOC容器接口ApplicationContext 接口实现方法为 类路径配置xml实现
     * 从IOC接口的实例化对象中调用bean,getBean(bean的id,bean的类)
     */
    @Test
    public void testA(){
        ApplicationContext context = new ClassPathXmlApplicationContext("JuiceA.xml");
        ListA listA = context.getBean("listA",ListA.class);
        MakerA makerA = context.getBean("makerA",MakerA.class);
        makerA.doWork();
        System.out.println("信息--"+listA.toString());
    }
}
  • 测试结果
  • 测试结果分析
    测试结果的数据符合预期结果。但是出现警告,该警告是因为Java 代码在编译后,默认是不保留方法的参数名称的,解决方法在组件类的构造方法上加入@ConstructorProperties({"name1","name2"})注释,在ListA中加入了该注释没有报警告,但是makerA中没有加就报警告了,如下图。

三、设值注入

设值注入是指通过setter方法传入被调用者的实例,从而实现依赖注入的一种方式。这种方式简单、直观,因此在Spring的依赖注入中大量使用。

3.1,基本组件类------ListB

package com.zjr.list;
public class ListB {
    private String fruit_sort;
    private String fruit_sugar;
    private String fruit_size;
    
    @Override
    public String toString() {
        return "ListB{" +
                "fruit_sort='" + fruit_sort + '\'' +
                ", fruit_sugar='" + fruit_sugar + '\'' +
                ", fruit_size='" + fruit_size + '\'' +
                '}';
    }

//set方法
    public void setFruit_sort(String fruit_sort) {
        this.fruit_sort = fruit_sort;
    }
    public void setFruit_sugar(String fruit_sugar) {
        this.fruit_sugar = fruit_sugar;
    }
    public void setFruit_size(String fruit_size) {
        this.fruit_size = fruit_size;
    }
}

3.2,基本组件类------MakerB

package com.zjr.juiceMaker;


import com.zjr.list.ListB;

/**
 * 基于setter方法的依赖注入
 */
public class MakerB {
    private ListB listB;
    public String customNumber;

    public void setListB(ListB listB){
        this.listB = listB;
    }
    public void setCustomNumber(String customNumber){
        this.customNumber = customNumber;
    }
    public void doWork(){
        System.out.println("请"+customNumber+"号顾客取餐");
    }
}

3.3,XML配置

  • 其他标签参考2.3,这里介绍property

  • 标签用于配置bean对象的属性,标签中的name属性表示要注入的bean属性名称,ref属性表示要注入的依赖bean的ID。

    <?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="listB" class="com.zjr.list.ListB">
    <property name="fruit_sort" value="贡茶"></property>
    <property name="fruit_sugar" value="无糖"></property>
    <property name="fruit_size" value="中杯"></property>
    </bean>

    <bean id="makerB" class="com.zjr.juiceMaker.MakerB">
    <property name="listB" ref="listB"></property>
    <property name="customNumber" value="002"></property>
    </bean>
    </beans>

3.4,测试

测试代码如下所示

import com.zjr.juiceMaker.MakerB;
import com.zjr.list.ListA;
import com.zjr.list.ListB;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class testMakerB {
    /**
     * 测试由JuiceB.xml配置的bean是否可以正常使用
     * 使用IOC容器接口ApplicationContext 接口实现方法为 类路径配置xml实现
     * 从IOC接口的实例化对象中调用bean,getBean(bean的id,bean的类)
     */
    @Test
    public void testB(){
        ApplicationContext context = new ClassPathXmlApplicationContext("JuiceB.xml");
        ListB listB = context.getBean("listB",ListB.class);
        MakerB makerB = context.getBean("makerB",MakerB.class);
        makerB.doWork();
        System.out.println("信息--"+listB.toString());
    }
}
  • 测试结果
  • 测试结果分析
    测试结果符合预期,成功调用了IOC所管理的bean以及使用其方法doWork。

总结

本次所举的例子也可以联系三层架构,控制层调用业务层,业务层调用数据层,然后把各层的各个组件配置进IOC容器,并完成DI。欢迎评论区交流。

相关推荐
七星静香20 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
Jacob程序员21 分钟前
java导出word文件(手绘)
java·开发语言·word
ZHOUPUYU22 分钟前
IntelliJ IDEA超详细下载安装教程(附安装包)
java·ide·intellij-idea
stewie625 分钟前
在IDEA中使用Git
java·git
Elaine20239140 分钟前
06 网络编程基础
java·网络
G丶AEOM42 分钟前
分布式——BASE理论
java·分布式·八股
落落鱼201342 分钟前
tp接口 入口文件 500 错误原因
java·开发语言
想要打 Acm 的小周同学呀43 分钟前
LRU缓存算法
java·算法·缓存
镰刀出海1 小时前
Recyclerview缓存原理
java·开发语言·缓存·recyclerview·android面试
阿伟*rui3 小时前
配置管理,雪崩问题分析,sentinel的使用
java·spring boot·sentinel