Spring-1-深入理解Spring XML中的依赖注入(DI):简化Java应用程序开发

学习目标

前两篇文章我们介绍了什么是Spring,以及Spring的一些核心概念,并且快速快发一个Spring项目,以及详细讲解IOC,今天详细介绍一些DI(依赖注入)

能够配置setter方式注入属性值

能够配置构造方式注入属性值

能够理解什么是自动装配

一、依赖注入(DI配置)

1 依赖注入方式【重点】

思考:向一个类中传递数据的方式有几种?(给类中的属性赋值)

  • setter方法

  • 构造方法

思考:依赖注入描述了在容器中建立bean与bean之间依赖关系的过程,注入数据类型有哪些?

  • 简单类型=八种基本数据类型+String

  • 引用类型

1.1 依赖注入的两种方式

  • setter注入
    • 简单类型

    • 引用类型(很常用)

  • 构造器注入
    • 简单类型

    • 引用类型

2 setter方式注入

思考:setter方式注入使用什么子标签?

property标签: 调用set方法赋值

name: 成员变量名, 准确来说对应set方法名,首字母大写

value: 对简单类型的成员变量赋值

ref: 对引用类型的成员变量赋值

2.1简单类型setter注入

格式:

<!-- property标签: 调用set方法赋值
       name: 成员变量名, 准确来说对应set方法名,首字母大写
       value: 对简单类型的成员变量赋值 -->
<property name="age" value="20"></property>

2.2 引用类型setter注入

格式:

<!--property标签: 调用set方法赋值
      name: 成员变量名, 准确来说对应set方法名,首字母大写
      ref: 对引用类型的成员变量赋值, 引用的对象 -->
<property name="studentDao" ref="studentDao">
</property>

2.3 setter注入代码实现

【第0步】创建项目
【第1步】导入Spring坐标
【第2步】导入Student实体类
【第3步】定义Spring管理的类(接口)
【第4步】创建Spring配置文件在resources目录下创建`application.xml`,配置setter的简单类型
【第5步】在test目录下创建`StudentServiceTest`,进行测试
【第6步】在`application.xml`,配置对应引用类型注入
【第7步】测试

【第0步】创建项目

【第1步】导入Spring坐标

  <dependencies>
      <!--导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>5.3.15</version>
      </dependency>

      <!-- 导入junit的测试包 -->
      <dependency>
          <groupId>org.junit.jupiter</groupId>
          <artifactId>junit-jupiter</artifactId>
          <version>5.8.2</version>
          <scope>test</scope>
      </dependency>

      <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.18.28</version>
      </dependency>
  </dependencies>

【第2步】导入Student实体类

@Data
@ToString
@AllArgsConstructor
public class Student {
    private String name;
    private String address;
    private Integer age;

    private Integer status;
}

【第3步】定义Spring管理的类(接口)

  • StudentDao接口和StudentDaoImpl实现类用于简单类型注入

package com.zbbmeta.dao;

public interface StudentDao {
    /**
     * 添加学生
     */
    void save();
}
public class StudentDaoImpl implements StudentDao {
    //简单类型属性
    private Integer age;
    public void setAge(Integer age) {
        this.age = age;
    }
    @Override
    public void save() {
        System.out.println("DAO: 年龄:"+this.age);
        System.out.println("DAO: 添加学生信息到数据库...");
    }
}
  • StudentService接口和StudentServiceImpl实现类用于引用类型注入

package com.zbbmeta.service;

public interface StudentService {
    /**
     * 添加学生
     */
    void save();
}

package com.zbbmeta.service.impl;

import com.zbbmeta.dao.StudentDao;
import com.zbbmeta.service.StudentService;


public class StudentServiceImpl implements StudentService {

    //创建成员对象
    private StudentDao studentDao ;

    //提供依赖对象对应的setter方法
    public void setStudentDao(StudentDao studentDao) {
        this.studentDao = studentDao;
    }
    
    @Override
    public void save() {
        System.out.println("Service: 添加学生信息到数据库...");
        studentDao.save();
    }
}

【第4步】创建Spring配置文件在resources目录下创建application.xml,配置setter的简单类型

  • 定义application.xml文件中创建StudentDao类到IOC容器,并实现简单类型注入

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

    <!-- 目标:setter简单类型注入-->
    <bean class="com.zbbmeta.dao.impl.StudentDaoImpl" id="studentDao">
<!--        property标签: 调用set方法赋值
            name: 成员变量名, 准确来说对应set方法名,首字母大写
            value: 对简单类型的成员变量赋值 -->
        <property name="age" value="20"></property>
    </bean>
</beans>

【第5步】在test目录下创建StudentServiceTest,进行测试

package com.zbbmeta;

import com.zbbmeta.dao.StudentDao;
import com.zbbmeta.service.StudentService;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StudentServiceTest {

    //目标:测试setter的简单类型的注入
    @Test
    public void test1(){

        //1.根据配置文件application.xml创建IOC容器
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");

        //2.从IOC容器里面获取id="bookService"对象
        StudentDao studentDao = (StudentDao) ac.getBean("studentDao");

        //3.执行对象方法
        studentDao.save();

        //4.关闭容器
        ac.close();
    }
  • 控制台结果:

【第6步】在application.xml,配置引用类型注入

    <!-- 目标:setter引用类型注入-->
    <bean class="com.zbbmeta.service.impl.StudentServiceImpl" id="studentService">
        <!--property标签: 调用set方法赋值
    name: 成员变量名, 准确来说对应set方法名,首字母大写
    ref: 对引用类型的成员变量赋值, 引用的对象 -->
        <property name="studentDao" ref="studentDao"></property>
    </bean>

【第7步】测试

    //目标:测试setter的引用类型的注入
    @Test
    public void test2(){
        //1.根据配置文件application.xml创建IOC容器
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
        //2.从IOC容器里面获取id="bookService"对象
        StudentService studentService = (StudentService) ac.getBean("studentService");
        //3.执行对象方法
        studentService.save();
        //4.关闭容器
        ac.close();
    }
  • 控制台结果

3 构造器方式注入

思考:构造方式注入使用什么子标签?

3.1 构造器注入简单类型

格式:配置中使用constructor-arg标签value属性注入简单类型

<!--constructor-arg标签: 调用构造函数方法赋值
    name: 成员变量名, 准确来说对应构造方法中参数名称
    value: 简单类型,方法参数对应的值-->
<constructor-arg name="age" value="30"></constructor-arg>

2.2 构造器注入引用类型

格式:配置中使用constructor-arg标签ref属性注入引用类型

<!--constructor-arg标签: 调用构造函数方法赋值
    name: 成员变量名, 准确来说对应构造方法中参数名称
    ref: 引用类型,属性注入引用类型对象-->
<constructor-arg name="studentDao" ref="studentDao"></constructor-arg>

3.3 构造器注入代码实现

【第0步】创建`11_2_DI_Construce`项目结构
【第1步】导入依赖坐标
【第2步】导入Student实体类
【第3步】定义Spring管理的类(接口)
【第4步】创建Spring配置文件在resources目录下创建`application.xml`,配置构造器注入简单类型
【第5步】在test目录下创建`StudentServiceTest`,进行测试
【第6步】在`application.xml`,配置构造器注入引用类型
【第7步】测试

【第0步】创建11_2_DI_Construce项目结构

【第1步】导入依赖坐标

和之前项目依赖一致

【第2步】导入Student实体类

和之前一致

【第3步】定义Spring管理的类(接口)

  • StudentDao接口和StudentDaoImpl实现类实现构造器注入简单类型

package com.zbbmeta.dao;

public interface StudentDao {
    /**
     * 添加学生
     */
    void save();
}
package com.zbbmeta.dao.impl;

import com.zbbmeta.dao.StudentDao;

public class StudentDaoImpl implements StudentDao {
    //简单类型属性
    private Integer age;

    public StudentDaoImpl(Integer age){
        System.out.println("DAO: 注入简单类型 age");
        this.age =age;
    }

    @Override
    public void save() {
        System.out.println("DAO: 年龄:"+this.age);
        System.out.println("DAO: 添加学生信息到数据库...");
    }
}

  • StudentService接口和StudentServiceImpl实现类实现构造器注入引用类型

package com.zbbmeta.service;

public interface StudentService {
    /**
     * 添加学生
     */
    void save();
}

package com.zbbmeta.service.impl;

import com.zbbmeta.dao.StudentDao;
import com.zbbmeta.service.StudentService;

public class StudentServiceImpl implements StudentService {

    //创建成员对象
    private StudentDao studentDao ;
    public StudentServiceImpl(StudentDao studentDao){
        System.out.println("StudentService: 注入引用类型studentDao");
        this.studentDao =studentDao;
    }
    @Override
    public void save() {
        System.out.println("Service: 添加学生信息到数据库...");
        studentDao.save();
    }
}

【第4步】创建Spring配置文件在resources目录下创建application.xml,配置构造器注入简单类型

  • 定义application.xml配置文件并配置StudentDaoImpl实现构造器注入简单类型

<?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 class="com.zbbmeta.dao.impl.StudentDaoImpl" id="studentDao">
        <!--constructor-arg标签: 调用构造函数方法赋值
            name: 成员变量名, 准确来说对应构造方法中参数名称
            value: 简单类型,方法参数对应的值-->
        <constructor-arg name="age" value="30"></constructor-arg>
    </bean>
</beans>

【第5步】在test目录下创建StudentServiceTest,进行测试

package com.zbbmeta;

import com.zbbmeta.dao.StudentDao;
import com.zbbmeta.service.StudentService;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StudentServiceTest {
    //目标:测试构造器的简单类型的注入
    @Test
    public void test1(){
        //1.根据配置文件application.xml创建IOC容器
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
        //2.从IOC容器里面获取id="studentDao"对象
        StudentDao studentDao = (StudentDao) ac.getBean("studentDao");
        //3.执行对象方法
        studentDao.save();
        //4.关闭容器
        ac.close();
    }
}
  • 控制台结果:

**【第6步】在application.xml,配置构造器注入引用类型 **

<!-- 目标:构造器依赖注入引用类型【了解】-->
<bean class="com.zbbmeta.service.impl.StudentServiceImpl" id="studentService">
    <!--constructor-arg标签: 调用构造函数方法赋值
        name: 成员变量名, 准确来说对应构造方法中参数名称
        ref: 引用类型,属性注入引用类型对象-->
    <constructor-arg name="studentDao" ref="studentDao"></constructor-arg>
</bean>

【第7步】测试

    //目标:测试setter的引用类型的注入
    @Test
    public void test2(){
        //1.根据配置文件application.xml创建IOC容器
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
        //2.从IOC容器里面获取id="bookService"对象
        StudentService studentService = (StudentService) ac.getBean("studentService");
        //3.执行对象方法
        studentService.save();
        //4.关闭容器
        ac.close();
    }
  • 控制台结果

4 依赖自动装配【理解】

4.1 自动装配概念

  • IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配

  • 自动装配方式
    • 按类型

    • 按名称

    • 按构造方法

autowire: 自动装配, 在容器中找对应对象,自动给成员变量赋值
    byType: 通过类型注入
    byName: 通过名字注入
    constructor: 通过构造器注入
    no: 不自动注入

4.2 自动装配类型

4.2.1 依赖类型自动装配

配置中使用bean标签autowire属性设置自动装配的类型byType

使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用

格式:

<!--给成员变量赋值
    autowire: 自动装配, 在容器中找对应对象,自动给成员变量赋值
        byType: 通过类型注入
        byName: 通过名字注入
        constructor: 通过构造器注入
        no: 不自动注入
-->
<bean class="com.zbbmeta.service.impl.StudentServiceImpl" id="studentService" autowire="byType">
</bean>

4.2.2依赖bean容器名字自动装配

配置中使用bean标签autowire属性设置自动装配的类型byName

使用按名称装配时(byName)必须保障容器中具有指定名称的bean,不推荐使用

<!--
autowire="byType" 根据成员属性名自动注入
-->
<bean class="com.zbbmeta.service.impl.StudentServiceImpl" id="studentService2" autowire="byName">
</bean>

4.2.3 依赖bean容器根据构造器自动装配注入

配置中使用bean标签autowire属性设置自动装配的类型constructor

<!--
autowire="constructor" 
据成员的所属类型去IOC容器中查找一样类型的对象进行调用构造函数进行给成员赋值
-->
<bean class="com.zbbmeta.service.impl.StudentServiceImpl" id="studentService3" autowire="constructor">
</bean>

4.3 依赖自动装配代码实现

【第0步】创建11_2_DI_Autowire项目
【第1步】导入依赖坐标
【第2步】导入Student实体类
【第3步】定义Spring管理的类(接口)
【第4步】创建Spring配置文件在resources目录下创建`application.xml`
【第5步】在test目录下创建`StudentServiceTest`

【第0步】创建11_2_DI_Autowire项目

【第1步】导入Spring坐标

和之前项目依赖一致

【第1步】导入依赖坐标

和之前一致

【第3步】定义Spring管理的类(接口)

  • StudentDao接口和StudentDaoImpl实现类

package com.zbbmeta.dao;

public interface StudentDao {
    /**
     * 添加学生
     */
    void save();
}
package com.zbbmeta.dao.impl;

import com.zbbmeta.dao.StudentDao;

public class StudentDaoImpl implements StudentDao {

    @Override
    public void save() {
        System.out.println("DAO: 添加学生信息到数据库...");
    }
}
  • StudentService接口和StudentServiceImpl实现类

package com.zbbmeta.service;

public interface StudentService {
    /**
     * 添加学生
     */
    void save();
}

package com.zbbmeta.service.impl;

import com.zbbmeta.dao.StudentDao;
import com.zbbmeta.service.StudentService;

public class StudentServiceImpl implements StudentService {

    //创建成员对象
    private StudentDao studentDao ;

    //提供依赖对象对应的setter方法
    public void setStudentDao(StudentDao studentDao)     {
        this.studentDao = studentDao;
    }

    //构造函数
    StudentServiceImpl(){}
    public StudentServiceImpl(StudentDao studentDao)    {
        System.out.println("Service 构造器方法");
        this.studentDao=studentDao;
    }

    @Override
    public void save() {
        System.out.println("Service: 添加学生信息到数据库...");
        studentDao.save();
    }
}

【第4步】创建Spring配置文件在resources目录下创建application.xml

  • 定义application.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
    目标:自动装配(自动注入)
    -->
    <bean class="com.zbbmeta.dao.impl.StudentDaoImpl" id="studentDao">
    </bean>
    <!--
     autowire="byType" 根据类型自动注入【重点】
     成员属性:private StudentDao studentDao ;  根据成员的所属类型去IOC容器中查找一样类型的对象进行调用成员的setStudentDao(参数)注入数据
    -->
    <bean class="com.zbbmeta.service.impl.StudentServiceImpl" id="studentService" autowire="byType"></bean>


    <!--
autowire="byName" 根据成员属性名自动注入
成员属性:private StudentDao studentDao ;  根据成员的属性名字去IOC容器中查找一样名称的对象进行调用成员的setStudentDao(参数)注入数据

-->
    <bean class="com.zbbmeta.service.impl.StudentServiceImpl" id="studentService2" autowire="byName"></bean>
    
    <!--
   autowire="constructor" 
   成员属性:private StudentDao studentDao
   构造函数:public StudentServiceImpl(StudentDao studentDao){
        this.studentDao = studentDao;
   }
   据成员的所属类型去IOC容器中查找一样类型的对象进行调用构造函数进行给成员赋值
  -->
    <bean class="com.zbbmeta.service.impl.StudentServiceImpl" id="studentService3" autowire="constructor"></bean>
</beans>

**【第5步】在test目录下创建StudentServiceTest进行测试

package com.zbbmeta;

import com.zbbmeta.dao.StudentDao;
import com.zbbmeta.service.StudentService;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StudentServiceTest {

    //目标:根据类型自动注入
    @Test
    public void test1(){

        //1.根据配置文件application.xml创建IOC容器
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
        //2.从IOC容器里面获取id="studentService"对象
        StudentService studentService = (StudentService) ac.getBean("studentService");
        //3.执行对象方法
        studentService.save();
        //4.关闭容器
        ac.close();
    }


    //目标:测试自动注入根据名称查找注入
    @Test
    public void test2(){
        //1.根据配置文件application.xml创建IOC容器
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
        //2.从IOC容器里面获取id="bookService"对象
        StudentService studentService = (StudentService) ac.getBean("studentService2");
        //3.执行对象方法
        studentService.save();
        //4.关闭容器
        ac.close();
    }


    //目标:测试构造器根据名称查找注入
    @Test
    public void test3(){
        //1.根据配置文件application.xml创建IOC容器
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
        //2.从IOC容器里面获取id="bookService"对象
        StudentService studentService = (StudentService) ac.getBean("studentService3");
        //3.执行对象方法
        studentService.save();
        //4.关闭容器
        ac.close();
    }
}

5 集合注入

5.1 注入数组类型数据

格式:

<!--调用setArray方法给成员array赋值-->
<property name="array">
    <array>
        <!--new String("数据") 引用类型赋值-->
        <bean class="java.lang.String" id="s">
            <constructor-arg value="100"></constructor-arg>
        </bean>
        <!--简单类型赋值-->
        <value>200</value>
        <value>300</value>
    </array>
</property>

5.2 注入List类型数据

格式:

<!--调用setList方法给成员list赋值-->
<property name="list">
    <list>
        <value>张三</value>
        <value>李四</value>
        <value>王五</value>
    </list>
</property>

5.3 注入Set类型数据

格式:

<!--调用setSet方法给成员set赋值-->
<property name="set">
    <set>
        <value>珠海</value>
        <value>江门</value>
        <value>惠州</value>
    </set>
</property>

5.4 注入Map类型数据

<!--调用setMap方法给成员map赋值-->
<property name="map">
    <map>
        <entry key="country" value="china"></entry>
        <entry key="province" value="广东"></entry>
        <entry key="city" value="广州"></entry>
    </map>
</property>

5.5 注入Properties类型数据

<!--调用setMap方法给成员map赋值-->
<property name="properties">
    <props>
        <prop key="country">china</prop>
        <prop key="province">广东</prop>
        <prop key="city">广州</prop>
    </props>
</property>

说明:property标签表示setter方式注入,构造方式注入constructor-arg标签内部也可以写<array>、<list>、<set>、<map>、<props>标签

5.6 集合注入完整代码

【第0步】在11_3_DI_Autowired的entity包下创建Person类
【第1步】创建Spring配置文件在resources目录下创建`application-person.xml`
【第2步】在test目录下创建`PersonTest`

【第0步】在11_3_DI_Autowired的entity包下创建Person类

package com.zbbmeta.entity;

import java.util.*;

public class Person {
    private String[] array;
    private List<String> list;
    private Set<String> set;
    private Map<String,Object> map;
    private Properties properties;


    public Person() {
    }

    public Person(String[] array, List<String> list, Set<String> set, Map<String, Object> map, Properties properties) {
        this.array = array;
        this.list = list;
        this.set = set;
        this.map = map;
        this.properties = properties;
    }

    /**
     * 获取
     * @return array
     */
    public String[] getArray() {
        return array;
    }

    /**
     * 设置
     * @param array
     */
    public void setArray(String[] array) {
        this.array = array;
    }

    /**
     * 获取
     * @return list
     */
    public List<String> getList() {
        return list;
    }

    /**
     * 设置
     * @param list
     */
    public void setList(List<String> list) {
        this.list = list;
    }

    /**
     * 获取
     * @return set
     */
    public Set<String> getSet() {
        return set;
    }

    /**
     * 设置
     * @param set
     */
    public void setSet(Set<String> set) {
        this.set = set;
    }

    /**
     * 获取
     * @return map
     */
    public Map<String, Object> getMap() {
        return map;
    }

    /**
     * 设置
     * @param map
     */
    public void setMap(Map<String, Object> map) {
        this.map = map;
    }

    /**
     * 获取
     * @return properties
     */
    public Properties getProperties() {
        return properties;
    }

    /**
     * 设置
     * @param properties
     */
    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "User{" +
                "array=" + Arrays.toString(array) +
                ", list=" + list +
                ", set=" + set +
                ", map=" + map +
                ", properties=" + properties +
                '}';
    }
}

【第1步】创建Spring配置文件在resources目录下创建application-person.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 http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
    目标:创建User对象并依赖注入赋值
    -->
    <bean class="com.zbbmeta.entity.Person" id="person">
        <!--调用setArray方法给成员array赋值-->
        <property name="array">
            <array>
                <!--new String("数据") 引用类型赋值-->
                <bean class="java.lang.String" id="s">
                    <constructor-arg value="100"></constructor-arg>
                </bean>
                <!--简单类型赋值-->
                <value>200</value>
                <value>300</value>
            </array>
        </property>
        <!--调用setList方法给成员list赋值-->
        <property name="list">
            <list>
                <value>张三</value>
                <value>李四</value>
                <value>王五</value>
            </list>
        </property>
        <!--调用setSet方法给成员set赋值-->
        <property name="set">
            <set>
                <value>珠海</value>
                <value>江门</value>
                <value>惠州</value>
            </set>
        </property>
        <!--调用setMap方法给成员map赋值-->
        <property name="map">
            <map>
                <entry key="country" value="china"></entry>
                <entry key="province" value="广东"></entry>
                <entry key="city" value="广州"></entry>
            </map>
        </property>
        <!--调用setMap方法给成员map赋值-->
        <property name="properties">
            <props>
                <prop key="country">china</prop>
                <prop key="province">广东</prop>
                <prop key="city">广州</prop>
            </props>
        </property>
    </bean>
</beans>

【第2步】在test目录下创建PersonTest

package com.zbbmeta;

import com.zbbmeta.entity.Person;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class PersonTest {
    @Test
    public void test(){

        //1.创建IOC容器
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("application-person.xml");

        //2.获取对象
        Person person = ac.getBean(Person.class); //根据指定类型去IOC容器中查找对象

        //3.打印对象
        System.out.println(person);

        //4.关闭容器
        ac.close();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/71246.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】每日一题---1

大家好&#xff0c;我是苏貝&#xff0c;本篇博客是系列博客每日一题的第一篇&#xff0c;本系列的题都不会太难&#xff0c;如果大家对这种系列的博客感兴趣的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 下面代码的结果是&#xff1a; #include <…

【Nginx】Nginx负载均衡

负载均衡&#xff1a;通过反向代理来实现 Nginx的七层代理和四层代理&#xff1a; 七层是最常用的反向代理方式&#xff0c;只能配置在nginx配置文件的http模块当中 &#xff1b;配置的方法名称为&#xff1a;upstream模块&#xff0c;不能写在server中也不能写在location中&a…

爬虫ip池越大越好吗?

作为一名资深的程序员&#xff0c;今天我要给大家分享一些关于爬虫ip池的知识。关于ip代理池的问题&#xff0c;答案是肯定的&#xff0c;池子越大越好。下面跟我一起来盘点一下ip池大的好处吧&#xff01; 1、提高稳定性 爬虫ip池越大&#xff0c;意味着拥有更多可用的爬虫ip…

大O表示法表示算法运行时间

大O表示法用来度量一个算法的运行时间。书写为O(n)&#xff0c;其中n为一个算法所执行的操作次数。当我们讨论算法的运行时间时&#xff0c;说的是一个算法在给定的输入列表增加的情况下算法执行操作数的增速&#xff0c;也就是运行时间的增速。 二分查找算法 下面介绍两种简…

锐捷设备密码管理、密码恢复、恢复出厂设置

目录 配置登录用户名密码以及Enable密码 只需要密码登录 需要用户名和密码登录&#xff08;无AAA&#xff09; 需要用户名和密码登录&#xff08;有AAA&#xff09; 密码恢复 Web密码忘记 Telnet/SSH密码忘记 Console密码忘记 所有密码都忘记&#xff0c;通过Console进…

Java GUI,mybatis实现资产管理系统

Java GUI——资产管理系统 前言&#xff1a;为了做java课设&#xff0c;学了一手Java GUI。感觉蛮有意思的&#xff0c;写写文章&#xff0c;做个视频记录一下。欢迎大家友善指出我的不足 资产管理系统录制视频&#xff0c;从头敲到尾 模块划分 资产信息管理 资产信息查询 …

SpringBoot在线失物招领系统

一个基于SpringBootSemanticUI的pc Web在线失物招领系统 http://localhost:8080/swzl/index 主页 http://localhost:8080/swzl/login 登录页 用户表user admin字段为true是管理员 false用户 springboot2.3 springmvc mybatis html ajax idea 或eclipse maven mys…

【Linux进行时】进程概念

进程的概念 什么是进程呢&#xff1f; ❓首先我们需要认识一下什么叫进程呢&#xff1f; 课本概念&#xff1a;程序的一个执行实例&#xff0c;正在执行的程序等 &#x1f525;内核观点&#xff1a;担当分配系统资源&#xff08;CPU时间&#xff0c;内存&#xff09;的实体。…

SpringBoot06---前端路由VueRouter

单页面应用&#xff0c;意思是只有一个html&#xff0c;变化的内容是不同组件进行切换&#xff0c;每个组件加载网络请求&#xff0c;渲染对应的数据&#xff0c;这个内容就是学习怎么完成组件切换 以网易云音乐为例&#xff1a; 网易云音乐 (163.com) 现在无需注册&#xf…

springBoot的日志文件

日志是程序的重要组成部分&#xff0c;主要可以用来定位和排查问题。除此之外&#xff0c;还可以用来&#xff1a; 1. 记录用户的登录日志&#xff0c;方便分析用户是正常登录还是恶意破解&#xff1b; 2. 记录系统的操作日志&#xff0c;方便数据恢复和定位操作人&#xff1b;…

docker 安装elasticsearch、kibana

下载es镜像 docker pull elasticsearch 启动es容器 docker run --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.typesingle-node" -e ES_JAVA_OPTS"-Xms512m -Xmx512m" -d elasticsearch 验证es界面访问 ​​​​​http://节点ip:9200/ ​…

leetcode 416. 分割等和子集

2023.8.12 太难了ToT.... 一题做了一个下午。 本题是动规题目的0-1背包问题系列。将分割子集转化为 在nums数组中任取任意元素使其和等于总元素和的一半&#xff0c;即可满足题目条件。 1、使用一个bool型二维dp数组&#xff0c;dp[i][j] 的含义是&#xff1a;任取nums数组在索…

已有公司将ChatGPT集成到客服中心以增强用户体验

Ozonetel正在利用ChatGPT来改善客户体验。该公司表示&#xff0c;他们通过使用ChatGPT收集与客户互动过程收集的“语料”能够更有针对性地提高服务效率&#xff0c;提供个性化的用户体验&#xff0c;并实现更高的客户满意度。[1] 通过这套解决方案&#xff0c;客服中心将拥有一…

27.Netty源码之FastThreadLocal

highlight: arduino-light FastThreadLocal FastThreadLocal 的实现与 ThreadLocal 非常类似&#xff0c;Netty 为 FastThreadLocal 量身打造了 FastThreadLocalThread 和 InternalThreadLocalMap 两个重要的类。下面我们看下这两个类是如何实现的。 FastThreadLocalThread 是对…

c++文件流详细笔记

c++流 IO :向设备输入数据和输出数据 C++的IO流 设备: 文件控制台特定的数据类型(stringstream)c++中,必须通过特定的已经定义好的类, 来处理IO(输入输出) 文件流 文件流: 对文件进行读写操作 头文件: 类库: ifstream 对文件输入(读文件) ofstream 对文件输出(写…

idea中如何处理飘红提示

idea中如何处理飘红提示 在写sql时&#xff0c;总是会提示各种错误 查找资料&#xff0c;大部分都是说关提示&#xff0c;这里把错误提示选择为None即可 关掉以后&#xff0c;也确实不显示任何提示了&#xff0c;但总有一种掩耳盗铃的感觉 这个sms表明明存在&#xff0c;但是还…

深度学习常用的python库学习笔记

文章目录 数据分析四剑客Numpyndarray数组和标量之间的运算基本的索引和切片数学和统计方法线性代数 PandasMatplotlibPIL 数据分析四剑客 Numpy Numpy中文网 ndarray 数组和标量之间的运算 基本的索引和切片 数学和统计方法 线性代数 Pandas Pandas中文网 Matplotlib Mat…

MuMu模拟器运行一段时间后Device.Present耗时突然上升

1&#xff09;MuMu模拟器运行一段时间后Device.Present耗时突然上升 2&#xff09;​如何在运行过程中获得温度信息 3&#xff09;Input System鼠标更换主按键的Bug 4&#xff09;如何禁止Unity向https://config.uca.cloud.unity3d.com发送设备信息 这是第347篇UWA技术知识分享…

Leetcode-每日一题【剑指 Offer 26. 树的子结构】

题目 输入两棵二叉树A和B&#xff0c;判断B是不是A的子结构。(约定空树不是任意一个树的子结构) B是A的子结构&#xff0c; 即 A中有出现和B相同的结构和节点值。 例如: 给定的树 A: 3 / \ 4 5 / \ 1 2 给定的树 B&#xff1a; 4 / 1 返回 true&#xff0…

C++笔记之静态成员函数的使用场景

C笔记之静态成员函数的使用场景 C静态成员函数的核心特点是不与特定类实例相关&#xff0c;可通过类名直接调用&#xff0c;用于执行与类相关的操作而无需创建类对象。其主要用途是在类级别上共享功能&#xff0c;管理全局状态或提供工具函数。 code review! 文章目录 C笔记之…