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。欢迎评论区交流。

相关推荐
Daniel 大东35 分钟前
BugJson因为json格式问题OOM怎么办
java·安全
Theodore_10225 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
冰帝海岸6 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象6 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了7 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
小二·7 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic7 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
懒洋洋大魔王7 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
武子康7 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神8 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式