spring-IOC

这篇具有很好参考价值的文章主要介绍了spring-IOC。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

IOC容器

简介

IoC(Inversion of Control)控制反转,是一种基于面向对象编程法则的设计思想,它设计出的程序具有松耦合、更优良的特点。
IoC容器是Spring框架中重要的核心组件之一,贯穿了Spring从出生到成长的整个过程,Spring通过IoC容器管理所有Java对象的实例化和初始化,控制对象与对象之间的实例化、初始化以及依赖关系。由IoC容器管理的Java对象称为Spring Bean,它与使用new 关键字创建的Java对象没有任何区别。

Bean管理:Bean对象的创建和Bean对象中属性的的赋值(或者叫Bean对象之间关系的维护)

控制反转,反转的是什么?

  • 将对象的创建权交出去,交给第三方容器负责。
  • 将对象和对象之间关系的维护权交出去,交给第三方容器负责。

如何实现控制反转?

DI(Dependency Injection) 依赖注入

依赖注入:指Spring创建对象的过程中,将对象依赖属性通过配置进行注入,它实现了控制反转的思想。当一个对象作为另一个对象的属性的时候,我们可以使用依赖注入的方式将对象的内容注入。

依赖注入的实现方式:①set注入、②构造注入


IoC在Spring中的实现

Spring的IoC容器中管理的组件叫做Bean, 在创建Bean之前,首先需要创建IoC容器,Spring提供的IoC容器有两种实现方式。

1、BeanFactory
这是IoC容器的基本实现,是Spring内部使用的接口
2、ApplicationContext
BeanFactory的子接口,提供了更多高级特性。面向Spring的使用者,几乎所有的场合都使用ApplicationContext而不是底层的BeanFactory

ApplicationContext的主要实现类

spring-IOC,Spring,spring,java,后端

类名 简介
ClassPathXmlApplicationContext 通过类读取路径下的XML格式的配置文件创建IoC对象
FileSystemXmlApplicationContext 通过文件系统路径读取XML格式的配置文件创建IoC对象
ConfigurableApplicationContext ApplicationContext的子接口,包含一些扩展方法refresh()和close(),让ApplicationContext具有启动、关闭和刷新上下文功能
WebApplicationContex 专门为Web应用准备,基于Web环境创建的IoC容器对象,并将对象引入存入ServletContext域中

基于xml管理Bean

步骤

①导入相关依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.0.9</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.20.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j2-impl</artifactId>
    <version>2.20.0</version>
</dependency>

②创建spring和log4j2的配置文件

spring.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 id="user" class="com.louis.ioc_xml.User"></bean>
</beans>

log4j2的配置文件可从取:https://blog.csdn.net/xry12354/article/details/131647570

③创建User对象

package com.louis.ioc_xml;

/**
 * @author XRY
 * @date 2023年06月22日13:58
 */
public class User {

    private String name;
    private Integer age;

    public void run(){
        System.out.println("run....");
    }
}

④获取Bean

方式一:根据id获取

由于id属性指定了bean的唯一标识,所以根据bean标签的id属性可以精确获取到一个组件对象。
写法:

<bean id="user" class="com.louis.ioc_xml.User"></bean>

id属性:唯一标识
class属性:要创建对象所在类的全路径(包名称+类名称)

@Test
public void testBeanById(){
    ApplicationContext applicationContext =
            new ClassPathXmlApplicationContext("bean.xml");
    User user = (User)applicationContext.getBean("user");
    logger.info("user = " + user);
}
/*[2023-06-22 14:17:20:953] [INFO] - TestBeanById.testBeanById(TestBeanById.java:20) - user = com.louis.ioc_xml.User@77d2e85*/

方式二:根据类型获取

@Test
public void testBeanByClass(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
    User bean = applicationContext.getBean(User.class);
    logger.info("user"+bean);
}
/*[2023-06-22 14:22:24:009] [INFO] - TestBeanById.testBeanByClass(TestBeanById.java:29) - usercom.louis.ioc_xml.User@1a9c38eb*/

方式三:根据id和类型获取

@Test
public void testBeanByClassAndId(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
    User user = applicationContext.getBean("user", User.class);
    logger.info("user" + user);
}
/*[2023-06-22 14:25:27:189] [INFO] - TestBeanById.testBeanByClassAndId(TestBeanById.java:37) - usercom.louis.ioc_xml.User@77d2e85*/
获取bean的细节

根据类型获取Bean时,要求IoC容器中指定类型的bean有且只能有一个。
组件类实现了接口,如果实现类只有一个则可以通过类型获取bean,如果实现类有多个,即使这些实现类都配置了bean也不能够使用类型获取。

只有一个实现类

//UserDaoImpl
package com.louis.bean;

/**
 * @author XRY
 * @date 2023年06月22日14:37
 */
public class UserDaoImpl implements UserDao{
    @Override
    public void run() {
        System.out.println("check the target");
    }
}

测试

@Test
public void testInterface(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
    UserDao userDao = applicationContext.getBean("userDao", UserDao.class);
    logger.info("userDao" + userDao);
    userDao.run();
}
/*[2023-06-22 14:43:27:092] [INFO] - TestBeanById.testInterface(TestBeanById.java:47) - userDaocom.louis.bean.UserDaoImpl@58ffcbd7
    check the target*/

User有多个实现类

//PersonDaoImpl
package com.louis.bean;

/**
 * @author XRY
 * @date 2023年06月22日14:47
 */
public class PersonDaoImpl implements UserDao{
    @Override
    public void run() {
        System.out.println("person");
    }
}

测试

@Test
public void testTwoInterface(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
    UserDao personDao = (UserDao)applicationContext.getBean("personDao");
    logger.info("personDao" + personDao);
    UserDao bean = applicationContext.getBean(UserDao.class);
    logger.info("bean" + bean);
}
 /*[2023-06-22 14:55:05:632] [INFO] - TestBeanById.testTwoInterface(TestBeanById.java:57) - personDaocom.louis.bean.PersonDaoImpl@555cf22
    org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.louis.bean.UserDao' available: expected single matching bean but found 2: userDao,personDao*/
结论

根据类型来获取bean时,在满足bean唯一性的前提下,其实只是看instanceof指定的类型的返回结果,只要返回的结果是true就可以认定为和类型匹配,能够获取到。
java中instanceof运算符用来判断前面的对象是否是后面的类,或其子类、实现类的实例。如果是返回true,否则返回false。


依赖注入

创建对象过程中,给属性设置值。

原生方法实现

package com.louis.di;

/**
 * @author XRY
 * @date 2023年06月23日9:46
 */
public class Book {
    private String name;
    private String author;

    public Book() {
    }

    public Book(String name, String author) {
        this.name = name;
        this.author = author;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }


    public static void main(String[] args){
        //使用原生方法实现值的设置
        //set
        Book book = new Book();
        book.setName("西游记");
        book.setAuthor("吴承恩");

        //构造器
        Book book1 = new Book("水浒传","施耐庵");
    }
}

基于setter注入

步骤

1、创建类,定义属性生成属性的set方法

package com.louis.di;

/**
 * @author XRY
 * @date 2023年06月23日9:46
 */
public class Book {
    private String name;
    private String author;
    

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                '}';
    }
}

2、在spring的配置文件中进行配置

<!--基于set方法进行注入-->
<bean id="book" class="com.louis.di.Book">
<!--在使用property这个标签时,就会调用类中的set方法-->
    <property name="name" value="红楼梦"></property>
    <property name="author" value="曹雪芹"></property>
</bean>

3、测试

@Test
public void testBook(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-di.xml");
    Book book = applicationContext.getBean("book", Book.class);
    logger.info("set注入" + book);
}

/*[2023-06-23 10:02:10:517] [INFO] - TestBeanById.testBook(TestBeanById.java:72) - set注入Book{name='红楼梦', author='曹雪芹'}*/

基于构造器注入

步骤

1、创建类,定义属性,生成有参构造方法(可以没有无参)

package com.louis.di;

/**
 * @author XRY
 * @date 2023年06月23日9:46
 */
public class Book {
    private String name;
    private String author;

    public Book() {
    }

    public Book(String name, String author) {
        this.name = name;
        this.author = author;
    }
    
    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                '}';
    }
}

2、在spring中进行配置

<!--构造器注入-->
<bean id="bookConstructor" class="com.louis.di.Book">
    <constructor-arg name="name" value="三国演义"></constructor-arg>
    <constructor-arg name="author" value="罗贯中"></constructor-arg>
<!--也可以使用index这种类型<constructor-arg index="0" value="三国"></constructor-arg>-->
</bean>

3、测试

@Test
public void testConstructor(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-di.xml");
    Book bookConstructor = applicationContext.getBean("bookConstructor", Book.class);
    logger.info("bookCon" + bookConstructor);
}
/*有参构造方法执行了
[2023-06-23 10:13:15:457] [INFO] - TestBeanById.testConstructor(TestBeanById.java:81) - bookConBook{name='三国演义', author='罗贯中'}*/

注入过程中特殊值的处理

字面量赋值

字面量
如:int a = 1;直接赋值,表示我们看到的这个数据本身。

<!-- 使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量 -->
<property name="name" value="张三"/>
null值
<bean id="book" class="com.louis.di.Book">
<!--在使用property这个标签时,就会调用类中的set方法-->
    <property name="name" value="红楼梦"></property>
    <property name="author">
        <null></null>
    </property>
</bean>
xml实体

当设置的值中有类似<>的时候,需要进行转义处理。解决方案:用xml实体来代替

 <property name="name" value="&lt;&gt;"></property>
CDATA节

它是xml中一种特殊的写法,当设置的值中有类似<>的时候,就是要写<>时可以使用。

<property name="name">
    <!--CDATA节中写什么符号都随意-->
    <value><![CDATA[ < >]]></value>
</property>

不同类型进行依赖注入

对象类型属性注入

如:部门和员工

Department
public class Department {
    private String dName;
    
    public void info(){
        System.out.println("Department name");
    }
}
Employee
public class Employee {
    private String eName;
    private Integer age;
    private Department dept;


    public void work(){
        System.out.println("Employee working");
    }
}
方式一:引用外部bean
1、生成它们的set方法

Department

//部门类
public class Department {
    private String dname;

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    public void info(){
        System.out.println("Department name");
    }
}

Employee

public class Employee {
    private String eName;
    private Integer age;
    private Department dept;

    public String geteName() {
        return eName;
    }

    public void seteName(String eName) {
        this.eName = eName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Department getDept() {
        return dept;
    }

    public void setDept(Department dept) {
        this.dept = dept;
    }

    public void work(){
        System.out.println("Employee working");
        //为了验证引入是否成功
        dept.info();
    }
}
2、编写配置文件
<!--引入外部bean
    1、创建两个类对象:department和employee
    2、在Employee标签里面,使用property引入两个类-->
<bean id="dept" class="com.louis.di_test.Department">
    <property name="dname" value="IT"></property>
</bean>
<bean id="emp" class="com.louis.di_test.Employee">
    <property name="eName" value="Alex"></property>
    <property name="age" value="18"></property>
<!--注入对象类型的熟属性-->
    <property name="dept" ref="dept"></property>
</bean>
3、测试
@Test
public void testObj(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diTest.xml");
    Employee emp = applicationContext.getBean("emp", Employee.class);
    emp.work();
    logger.info("emp" + emp);
}
/*Employee working
Department name
[2023-06-23 11:45:56:941] [INFO] - TestBeanById.testObj(TestBeanById.java:92) - empEmployee{eName='Alex', age=18, dept=Department{dname='IT'}}
*/
方式二:内部bean
1、生成set方法
2、编写配置文件
<!--内部bean注入-->
<bean id="emp2" class="com.louis.di_test.Employee">
    <property name="eName" value="Louie"></property>
    <property name="age" value="20"></property>
    <!--内部bean-->
    <property name="dept">
        <bean id="dept2" class="com.louis.di_test.Department">
            <property name="dname" value="设计"></property>
         </bean>
    </property>
</bean>
3、测试
@Test
public void testObj2(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diTest.xml");
    Employee emp2 = applicationContext.getBean("emp2", Employee.class);
    emp2.work();
    logger.info("emp2" + emp2);
}
/*
Employee working
Department name
[2023-06-23 11:54:58:543] [INFO] - TestBeanById.testObj2(TestBeanById.java:104) - emp2Employee{eName='Louie', age=20, dept=Department{dname='设计'}}
*/
方式三:级联属性赋值
1、创建实体对象,生成set方法
2、编写配置文件
<!--级联赋值-->
<bean id="dept3" class="com.louis.di_test.Department">
    <property name="dname" value="超人组"></property>
</bean>
<bean id="emp3" class="com.louis.di_test.Employee">
    <property name="eName" value="khan"></property>
    <property name="age" value="23"></property>
    <property name="dept" ref="dept3"></property>
    <property name="dept.dname" value="研发科"></property>
</bean>
3、测试
@Test
public void testObj3(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diTest.xml");
    Employee emp3 = applicationContext.getBean("emp3", Employee.class);
    emp3.work();
    logger.info("emp3" + emp3);
}

/*Employee working
Department name
[2023-06-23 12:02:44:654] [INFO] - TestBeanById.testObj3(TestBeanById.java:118) - emp3Employee{eName='khan', age=23, dept=Department{dname='研发科'}}*/
为数组类型属性赋值
1、编写实体类
public class Person {
    private String[] hobby;

    public String[] getHobby() {
        return hobby;
    }

    public void setHobby(String[] hobby) {
        this.hobby = hobby;
    }

    @Override
    public String toString() {
        return "Person{" +
                "hobby=" + Arrays.toString(hobby) +
                '}';
    }
}
2、编写配置文件
 <!--注入数组类型的属性-->
<bean id="person" class="com.louis.di_array.Person">
    <!--注入数组类型属性值-->
    <property name="hobby">
        <array>
            <value>eat</value>
            <value>sleep</value>
            <value>code</value>
        </array>
    </property>
</bean>
3、测试
@Test
public void testArray(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diarray.xml");
    Person person = applicationContext.getBean("person", Person.class);
    logger.info("person" + person);
}

/*[2023-06-23 12:14:00:835] [INFO] - TestBeanById.testArray(TestBeanById.java:129) - personPerson{hobby=[eat, sleep, code]}*/
为集合类型属性赋值
(一)为list集合类型属性赋值
1、编写实体类并生成set方法

Department

public class Department {
    private String dname;
    private List<Employee> empList;

    public List<Employee> getEmpList() {
        return empList;
    }

    public void setEmpList(List<Employee> empList) {
        this.empList = empList;
    }

    public String getDname() {
        return dname;
    }

    public void setDname(String dname) {
        this.dname = dname;
    }

    public void info(){
        System.out.println("Department name");
    }

    @Override
    public String toString() {
        return "Department{" +
                "dname='" + dname + '\'' +
                ", empList=" + empList +
                '}';
    }
}

Employee

public class Employee {
    private String eName;
    private Integer age;
    private Department dept;

    public String geteName() {
        return eName;
    }

    public void seteName(String eName) {
        this.eName = eName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Department getDept() {
        return dept;
    }

    public void setDept(Department dept) {
        this.dept = dept;
    }

    public void work(){
        System.out.println("Employee working");
        dept.info();
    }

    @Override
    public String toString() {
        return "Employee{" +
                "eName='" + eName + '\'' +
                ", age=" + age +
                ", dept=" + dept +
                '}';
    }
}
2、编写配置文件
<!--实现list集合注入-->
<bean id="emp" class="com.louis.di_test.Employee">
    <property name="eName" value="Louis"></property>
    <property name="age" value="23"></property>
</bean>
<bean id="empTwo" class="com.louis.di_test.Employee">
    <property name="eName" value="Alex"></property>
    <property name="age" value="22"></property>
</bean>
<bean id="dept" class="com.louis.di_test.Department">
    <property name="dname" value="研发科"></property>
    <property name="empList">
        <list>
<!--如果是字符串和基本数据类型,可以直接使用<value>标签-->
            <ref bean="emp"></ref>
            <ref bean="empTwo"></ref>
        </list>
    </property>
</bean>
3、测试
@Test
public void testList(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-dilist.xml");
    Department dept = applicationContext.getBean("dept", Department.class);
    dept.info();
    logger.info("dept" + dept);
}

/*Department name
employee.geteName() = Louis
employee.geteName() = Alex
[2023-06-23 12:31:05:121] [INFO] - TestBeanById.testList(TestBeanById.java:139) - deptDepartment{dname='研发科', empList=[Employee{eName='Louis', age=23, dept=null}, Employee{eName='Alex', age=22, dept=null}]}
*/
(二)为Map集合属性注入值
1、编写实体类并生成set方法

Student

public class Student {
    private String sname;
    private String sid;
    //一个学生可能对应多个老师
    private Map<String, Teacher> teacherMap;

    public Map<String, Teacher> getTeacherMap() {
        return teacherMap;
    }

    public void setTeacherMap(Map<String, Teacher> teacherMap) {
        this.teacherMap = teacherMap;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }
    
    public void learn(){
        System.out.println("学生姓名" + sname + "----" + "学号" + sid);
        System.out.println(teacherMap);
    }

    @Override
    public String toString() {
        return "Student{" +
                "sname='" + sname + '\'' +
                ", sid='" + sid + '\'' +
                ", teacherMap=" + teacherMap +
                '}';
    }
}

Teacher

public class Teacher {
    private String tname;
    private String tid;

    public String getTname() {
        return tname;
    }

    public void setTname(String tname) {
        this.tname = tname;
    }

    public String getTid() {
        return tid;
    }

    public void setTid(String tid) {
        this.tid = tid;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "tname='" + tname + '\'' +
                ", tid='" + tid + '\'' +
                '}';
    }
}
2、编写配置文件
    <!--
    1、创建两个对象
    2、注入普通类型属性
    3、在学生bean注入map集合类型属性
    -->
<bean id="teacher" class="com.louis.di_map.Teacher">
    <property name="tid" value="110"></property>
    <property name="tname" value="Alex"></property>
</bean>
<bean id="teacher2" class="com.louis.di_map.Teacher">
    <property name="tid" value="120"></property>
    <property name="tname" value="Khan"></property>
</bean>
<bean id="student" class="com.louis.di_map.Student">
    <property name="sid" value="18162004"></property>
    <property name="sname" value="Louie"></property>
    <property name="teacherMap">
        <map>
            <entry>
                <key>
                    <value>key1</value>
                </key>
                <ref bean="teacher"></ref>
            </entry>
            <entry>
                <key>
                    <value>key2</value>
                </key>
                <ref bean="teacher2"></ref>
            </entry>
        </map>
    </property>
</bean>
3、测试
@Test
public void testMap(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diMap.xml");
    Student student = applicationContext.getBean("student", Student.class);
    logger.info("student" + student);
    student.learn();
}

/*[2023-06-23 12:57:29:327] [INFO] - TestBeanById.testMap(TestBeanById.java:152) - studentStudent{sname='Louie', sid='18162004', teacherMap={key1=Teacher{tname='Alex', tid='110'}, key2=Teacher{tname='Khan', tid='120'}}}
学生姓名Louie----学号18162004
{key1=Teacher{tname='Alex', tid='110'}, key2=Teacher{tname='Khan', tid='120'}}*/
引用集合类型的bean

将list和map的实现方式换一种写法。

1、在原有的Student和Teacher的基础上,再添加一个Lesson类
public class Lesson {
    private String lessonName;

    public String getLessonName() {
        return lessonName;
    }

    public void setLessonName(String lessonName) {
        this.lessonName = lessonName;
    }

    @Override
    public String toString() {
        return "Lesson{" +
                "lessonName='" + lessonName + '\'' +
                '}';
    }
}
2、再Student类中添加课程列表
List<Lesson> list;

public List<Lesson> getList() {
    return list;
}

public void setList(List<Lesson> list) {
    this.list = list;
}
3、编写配置文件

加上util的命名空间引入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
    1、创建三个对象
    2、注入普通类型属性
    3、使用util:类型 定义。需要更改命名空间引入
    4、在学生bean引入util:类型定义bean,完成list、map类型注入
    -->
    <bean id="lessonOne" class="com.louis.di_map.Lesson">
        <property name="lessonName" value="JAVA开发"></property>
    </bean>
    <bean id="lessonTwo" class="com.louis.di_map.Lesson">
        <property name="lessonName" value="Python 开发"></property>
    </bean>
    <bean id="teacherOne" class="com.louis.di_map.Teacher">
        <property name="tname" value="Louie"></property>
        <property name="tid" value="11011"></property>
    </bean>
    <bean id="teacherTwo" class="com.louis.di_map.Teacher">
        <property name="tname" value="Alex"></property>
        <property name="tid" value="12012"></property>
    </bean>
    <bean id="student" class="com.louis.di_map.Student">
        <property name="sname" value="khan"></property>
        <property name="sid" value="201811011"></property>
        <!--注入list、map类型的属性-->
        <property name="list" ref="lessonList"></property>
        <property name="teacherMap" ref="teacherMap"></property>
    </bean>
    <util:list id="lessonList">
        <ref bean="lessonOne"></ref>
        <ref bean="lessonTwo"></ref>
    </util:list>
    <util:map id="teacherMap">
        <entry>
            <key>
                <value>111</value>
            </key>
            <ref bean="teacherOne"></ref>
        </entry>
        <entry>
            <key>
                <value>222</value>
            </key>
            <ref bean="teacherTwo"></ref>
        </entry>
    </util:map>
</beans>
4、测试
@Test
public void testUtil(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diRef.xml");
    Student student = applicationContext.getBean("student", Student.class);
    student.learn();
    logger.info("student" + student);
}

/*学生姓名khan----学号201811011
{111=Teacher{tname='Louie', tid='11011'}, 222=Teacher{tname='Alex', tid='12012'}}
[2023-06-23 14:28:04:062] [INFO] - TestBeanById.testUtil(TestBeanById.java:164) - studentStudent{sname='khan', sid='201811011', teacherMap={111=Teacher{tname='Louie', tid='11011'}, 222=Teacher{tname='Alex', tid='12012'}}, list=[Lesson{lessonName='JAVA开发'}, Lesson{lessonName='Python 开发'}]}
*/
p命名空间

命名空间:为避免命名时冲突,再命名后面加上:重命名的方式

xmlns:p = "http://www.springframework.org/schema/p"
编写配置文件
<!--p命名空间注入-->
<bean id="studentP" class="com.louis.di_map.Student" p:sid="201811" p:sname="Louis" p:list-ref="lessonList" p:teacherMap-ref="teacherMap">
</bean>
<util:list id="lessonList">
    <ref bean="lessonOne"></ref>
    <ref bean="lessonTwo"></ref>
</util:list>
<util:map id="teacherMap">
    <entry>
        <key>
            <value>111</value>
        </key>
        <ref bean="teacherOne"></ref>
    </entry>
    <entry>
        <key>
            <value>222</value>
        </key>
        <ref bean="teacherTwo"></ref>
    </entry>
</util:map>
测试
@Test
public void testP(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diRef.xml");
    Student studentP = applicationContext.getBean("studentP", Student.class);
    studentP.learn();
    logger.info("studentP" + studentP);
}

/*学生姓名Louis----学号201811
{111=Teacher{tname='Louie', tid='11011'}, 222=Teacher{tname='Alex', tid='12012'}}
[2023-06-23 14:43:14:562] [INFO] - TestBeanById.testP(TestBeanById.java:176) - studentPStudent{sname='Louis', sid='201811', teacherMap={111=Teacher{tname='Louie', tid='11011'}, 222=Teacher{tname='Alex', tid='12012'}}, list=[Lesson{lessonName='JAVA开发'}, Lesson{lessonName='Python 开发'}]}
*/

引入外部属性文件

应用场景:在一个文件中如果出现多个bean的创建和注入,维护就会比较困难。可以将一些特定的文件放在特定位置在spring中进行引入,如数据库文件。

实现步骤(数据库的配置文件引入)
1、引入相关依赖
 <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.16</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils -->
<dependency>
    <groupId>commons-dbutils</groupId>
    <artifactId>commons-dbutils</artifactId>
    <version>1.7</version>
</dependency>
2、创建Dbutils.properties
username=root
password=root
url=jdbc:mysql://localhost:3306/spring
driver=com.mysql.cj.jdbc.Driver
3、创建spring的配置文件

引入context命名空间,引入属性文件,使用表达式完成注入。

context命名空间

xmlns:contex="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"

引入属性文件

<!--引入外部属性文件-->
<contex:property-placeholder location="classpath:Dbutils.properties"></contex:property-placeholder>

完整配置文章来源地址https://www.toymoban.com/news/detail-602298.html

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:contex="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--引入外部属性文件-->
    <contex:property-placeholder location="classpath:Dbutils.properties"></contex:property-placeholder>
<!--完成数据库信息注入-->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="url" value="${url}"></property>
        <property name="username" value="${username}"></property>
        <property name="password" value="${password}"></property>
        <property name="driver" value="${driver}"></property>
    </bean>
</beans>
4、测试
@Test
public void testDbutils(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-Dbutils.xml");
    DruidDataSource dataSource = applicationContext.getBean("druidDataSource", DruidDataSource.class);
    logger.info("dataSource" + dataSource);
}
/*
* [2023-06-23 15:36:52:008] [INFO] - TestBeanById.testDbutils(TestBeanById.java:189) - dataSource{
    CreateTime:"2023-06-23 15:36:51",
    ActiveCount:0,
    PoolingCount:0,
    CreateCount:0,
    DestroyCount:0,
    CloseCount:0,
    ConnectCount:0,
    Connections:[
    ]
}
* */

到了这里,关于spring-IOC的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring IOC容器:让Java对象的管理和配置更简单

    在Java开发中,我们经常需要创建和使用各种Java对象,例如实体类,服务类,控制器类等。这些对象之间通常存在着一定的依赖关系,例如一个服务类可能需要调用另一个服务类或一个数据访问类的方法。为了创建和使用这些对象,我们通常需要做以下几件事: 在代码中通过

    2024年02月11日
    浏览(40)
  • Java Spring IoC&DI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性

    💓 博客主页:从零开始的-CodeNinja之路 ⏩ 收录文章:Java Spring IoCDI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性 🎉欢迎大家点赞👍评论📝收藏⭐文章 我们一下要学习的内容都是为了实现⾼内聚低耦合来进行的 软件设计原则:⾼内聚低耦合. ⾼内聚指

    2024年04月15日
    浏览(48)
  • Java面试题:你知道Spring的IOC吗?那么,它为什么这么重要呢?

    Spring的IOC(控制反转)是一种设计模式,它允许开发者将对象的创建和管理交给Spring框架来完成。在Spring中,IOC允许开发者将对象依赖关系从代码中分离出来,从而使代码更加灵活、可重用和易于管理。 IoC 全称Inverse of Control( 反向控制或控制反转 )。 在类和类之间存在控

    2024年04月28日
    浏览(99)
  • Java后端07(Spring)

    ​涉及的设计模式:单例模式,简单工厂模式,代理模式,观察者模式,反射,注解。。。。。 ​在传统模式下,对象的创建和赋值,都是由开发者自己手动完成,事实情况下,开发者只关心如何获取赋值好的对象,但是并不希望自己手动进行创建对象和赋值的事情(sprin

    2024年02月13日
    浏览(36)
  • Java后端07(Spring未完成)

    ​涉及的设计模式:单例模式,简单工厂模式,代理模式,观察者模式,反射,注解。。。。。 ​在传统模式下,对象的创建和赋值,都是由开发者自己手动完成,事实情况下,开发者只关心如何获取赋值好的对象,但是并不希望自己手动进行创建对象和赋值的事情(sprin

    2024年02月14日
    浏览(51)
  • JAVA后端开发面试基础知识(八)——Spring

    Spring是一个轻量级Java开发框架 我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发,比如说 Spring 支持 IoC(Inverse of Control:控制反转) 和 AOP(Aspect-Oriented Programming:面向切面编程)、可以很方便地对数据库进行访问、

    2024年03月10日
    浏览(74)
  • Spring IOC:IOC在Spring底层中如何实现?

    编译软件:IntelliJ IDEA 2019.2.4 x64 操作系统:win10 x64 位 家庭版 Maven版本:apache-maven-3.6.3 Mybatis版本:3.5.6 spring版本:5.3.1 第一章:初识Spring:如何在Maven工程上搭建Spring框架? 第二章:Spring IOC:IOC在Spring底层中如何实现? IOC ,英文全称为Inversion of Control,意为 反转控制 。不

    2024年02月03日
    浏览(39)
  • 微信小程序的授权登录-Java 后端 (Spring boot)

    微信开发文档链接:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 一个可以测试的微信小程序 此微信小程序的APPID和APPscret(至开发者后台获取) 从时序图我们可以了解到流程大致分为两步: 小程序端获取code后传给Java后台 Java后台获取code后向微信后台接口

    2024年02月09日
    浏览(55)
  • Spring——Spring IOC原理

    IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器

    2024年02月09日
    浏览(48)
  • 【Spring】Spring对IoC的实现

    根据 【动力节点】最新Spring框架教程,全网首套Spring6教程,跟老杜从零学spring入门到高级 以及老杜的原版笔记 https://www.yuque.com/docs/share/866abad4-7106-45e7-afcd-245a733b073f?# 《Spring6》 进行整理, 文档密码:mg9b Spring 相关文章整理汇总归纳于:https://www.yuque.com/u27599042/zuisie IoC 控制

    2024年02月15日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包