手撕Spring5框架(三)IOC操作Bean管理(基于XML)

什么是Bean管理?

通常是指依据Spring进行的两个操作:

1)Spring创建对象

2)Spring注入属性

Bean管理的两种实现方式:

  • 基于XML方式

  • 基于注解方式

IOC操作Bean管理(基于XML)

通过Spring去管理Bean我们下面具体讲解实现管理的两种方式:

  • 基于xml方式创建对象

在之前入门案例章节我们已经初步认识了Spring基于xml方式创建对象。

<!--通过Spring配置User对象-->
<bean id="user" class="org.learn.spring5.User"></bean>

基本描述:

1)在Spring配置文件中,使用bean标签,标签里添加相应属性,就可以实现对象的创建。

2)在bean标签中包含许多属性

3)创建对象时,默认也是执行无参构造方法完成对象的创建。

bean标签下常用的几个属性介绍:

id:唯一标识,不能添加特殊符号

class:类的全路径,

name:定义对象的标识,可以加特殊符号

  • 基于xml方式注入属性

DI:依赖注入,就是注入属性

  1. 第一种方式使用set方式注入

    (1)创建类,定义属性和对应的set方法

package org.learn.spring5;

public class User {

    private String userName;
    private Integer age;
    
       public void setUserName(String userName) {
        this.userName = userName;
    }

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

    public void addUser() {

        System.out.println("添加一个用户。。。。");
    }

    public void getUserInfo() {
        System.out.println("userName:" + userName);
        System.out.println("age:" + age);

    }
}

 (2)在Spring配置文件中,配置对象创建、配置属性注入

<?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 id="user" class="org.learn.spring5.User">
        <!--property标签设置set的属性 -->
        <property name="userName" value="joh"></property>
        <property name="age" value="11"></property>
    </bean>

</beans>

(3)编写测试程序

package org.learn.spring5;


import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpring5 {
    @Test
    public void test() {
        //1.加载spring的配置文件
        BeanFactory context = new ClassPathXmlApplicationContext("bean1.xml");
        //2.获取配置创建的对象
        //第一个参数是配置文件中配置的User对象的ID
        User user = context.getBean("user", User.class);
        System.out.println(user);
        user.addUser();
        user.getUserInfo();
    }
}

执行测试方法得到结果如下:

 org.learn.spring5.User@12c8a2c0
 添加一个用户。。。。
 userName:joh
 age:11

2.第二种方式使用构造函数注入

(1)创建类,定义属性和对应的构造方法

package org.learn.spring5;

public class Order {

    private String orderNo;

    private String address;

    public Order(String orderNo, String address) {
        this.orderNo = orderNo;
        this.address = address;
    }

    public void orderIno(){
        System.out.println("orderNo:"+orderNo);
        System.out.println("address:"+address);
    }
}

(2)在Spring配置文件中,配置对象创建、配置属性注入

 <!--使用构造的方式注入属性-->
    <bean id="order" class="org.learn.spring5.Order">
        <constructor-arg name="orderNo" value="12333"></constructor-arg>
        <constructor-arg name="address" value="china"></constructor-arg>
    </bean>

(3)编写测试程序

 @Test
    public void test2() {
        //1.加载spring的配置文件
        BeanFactory context = new ClassPathXmlApplicationContext("bean1.xml");
        //2.获取配置创建的对象
        //第一个参数是配置文件中配置的User对象的ID
        Order order = context.getBean("order", Order.class);
        System.out.println(order);
        order.orderIno();
    }

执行测试方法得到结果如下:

org.learn.spring5.Order@fcd6521
orderNo:12333
address:china

3.Set方法注入的另一种方式,p命名空间

(1)在Spring配置文件中,配置对象创建、使用P命名空间配置属性注入

<!--使用P命名空间注入属性,简化set属性注入的方式-->
    <bean id="user1" class="org.learn.spring5.User" p:userName="jack" p:age="15">
    </bean>

 (2)编写测试程序

    /**
     * P命名空间方式注入属性
     */
    @Test
    public void test3() {
        //1.加载spring的配置文件
        BeanFactory context = new ClassPathXmlApplicationContext("bean1.xml");
        //2.获取配置创建的对象
        //第一个参数是配置文件中配置的User对象的ID
        User user = context.getBean("user1", User.class);
        System.out.println(user);
        user.addUser();
        user.getUserInfo();
    }

执行测试方法得到结果

org.learn.spring5.User@6dde5c8c
添加一个用户。。。。
userName:jack
age:15

注入空值和特殊符号

1)空值

<!--向属性值中设置空值-->
        <property name="email">
            <null />
        </property>

2)特殊符号

 <!--属性值包含特殊符号 <>
    1.转义<>
    2.CDATA
    -->
    <property name="email">
        <value>
            <![CDATA[<<[email protected]>>]]>
        </value>
    </property>

注入属性-外部bean

场景:UserService和UserDao的关系

步骤:1)创建UserService类和UserDao接口、UserDAOImpl实现类

package org.learn.spring5.service;

import org.learn.spring5.dao.UserDao;

public class UserService {

    //创建userDao属性,生成set方法

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void userAdd() {
        //调用 userDao对象的userAdd方法
        System.out.println("service userAdd");
        userDao.userAdd();

    }
}
package org.learn.spring5.dao;

public interface UserDao {

    int userAdd();
}
package org.learn.spring5.dao.impl;

import org.learn.spring5.dao.UserDao;

public class UserDaoImpl implements UserDao {
    public int userAdd() {
        System.out.println("UserDao userAdd");
        return 0;
    }
}

 2)在bean2.xml配置文件中创建对象UserDao和UserDao,并且在UserService对象中注入UserDao属性

<?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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--创建对象UserService-->
  <bean id="userService" class="org.learn.spring5.service.UserService">
      <!--注入外部bean-->
      <!--ref属性:是UserDaoImpl对象的id值-->
      <property name="userDao" ref="userDaoImpl"></property>
  </bean>
    <!--创建对象UserDaoImpl-->
    <bean id="userDaoImpl" class="org.learn.spring5.dao.impl.UserDaoImpl"></bean>
</beans>

3)创建测试程序  

 /**
     *注入属性-外部bean
     */
    @Test
    public void test4() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
       UserService userService =  context.getBean("userService", UserService.class);
       userService.userAdd();
    }

 执行测试方法得到的结果

service userAdd
UserDao userAdd

 注入属性-内部bean

场景:一对多关系: 班级和学生的关系

一个班级有多个学生,一个学生只属于一个班级

在实体类中表示一对多的关系

1)创建类和属性

package org.learn.spring5.bean;

//班级类
public class Classes {

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

    private String name;

    @Override
    public String toString() {
        return "Classes{" +
                "name='" + name + '\'' +
                '}';
    }
}
package org.learn.spring5.bean;

//学生类
public class Student {

    //学生名称
    private String studentName;
    //学生的年龄
    private String age;

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

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

    public void setClasses(Classes classes) {
        this.classes = classes;
    }

    //学生所属的班级
    private Classes classes;


    public void add() {
        System.out.println("studentName:" + studentName + "----" + "age:" + age);
        System.out.println("classes:" + classes);
    }
}

2)创建配置文件

<?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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--注入属性-内部bean-->

    <!--创建对象-->
    <bean id="student" class="org.learn.spring5.bean.Student">
        <!--设置对象属性-->
        <property name="studentName" value="xiaoming"></property>
        <property name="age" value="15"></property>
        <!--配置内部bean-->
        <property name="classes">
            <bean id="classes" class="org.learn.spring5.bean.Classes">
                <property name="name" value="初三一班"></property>

            </bean>

        </property>
    </bean>


</beans>

3)创建测试程序

    /**
     * 注入属性-内部bean
     */
    @Test
    public void test5() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
        Student student = context.getBean("student", Student.class);
        student.add();
    }

 执行测试方法得到的结果

studentName:xiaoming----age:15
classes:Classes{name='初三一班'}

注入属性-级联赋值

方式1:

配置文件中设置

<!--注入属性-级联赋值-->
    <!--方式1-->
    <!--创建对象-->
    <bean id="student" class="org.learn.spring5.bean.Student">
        <!--设置对象属性-->
        <property name="studentName" value="xiaoming"></property>
        <property name="age" value="15"></property>
        <!--级联赋值-->
        <property name="classes" ref="classes"></property>
    </bean>
    <bean id="classes" class="org.learn.spring5.bean.Classes">
        <property name="name" value="初三一班"></property>
    </bean>

方式2:

Student类中class属性增加get方法

 //学生所属的班级
    private Classes classes;


    public Classes getClasses() {
        return classes;
    }

配置文件中设置

 <bean id="student" class="org.learn.spring5.bean.Student">
         <!--设置对象属性-->
         <property name="studentName" value="xiaoming"></property>
         <property name="age" value="15"></property>
         <!--级联赋值-->
         <property name="classes" ref="classes"></property>
         <property name="classes.name" value="初三二班"></property>
     </bean>
     <bean id="classes" class="org.learn.spring5.bean.Classes">
     </bean>

IOC操作Bean管理-注入集合属性

1)注入数组类型属性

2)注入集合类型属性

3)注入Map类型属性

4)集合里设置对象的值

第一步:创建类

package org.learn.spring5.bean;


import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

//班级类
public class Classes {

    //数组类型
    private String[] student;
    //集合类型
    private List<String> list;
    //map类型
    private Map<String, String> maps;

    public void setStudents(List<Student> students) {
        this.students = students;
    }

    //对象类型
    private List<Student> students;


    public void setStudent(String[] student) {
        this.student = student;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setMaps(Map<String, String> maps) {
        this.maps = maps;
    }


    public void test() {
        System.out.println(Arrays.toString(student));
        System.out.println(list);
        System.out.println(maps);
        System.out.println(students);

    }
}
package org.learn.spring5.bean;


//學生類
public class Student {

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

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

    //学生名称
    private String name;

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

    //年龄
    private int age;
}

第二步:创建Spring配置文件

<?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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--IOC操作Bean管理-注入集合属性-->

    <bean id="classes" class="org.learn.spring5.bean.Classes">
            <!--数组类型的属性注入-->
    <property name="student">
        <array>
            <value>zhangsan</value>
            <value>lisi</value>
            <value>wangwu </value>
        </array>

    </property>
            <!--集合类型的属性注入-->
        <property name="list">
            <list>
                <value>list1</value>
                <value>list2</value>
                <value>list3</value>
            </list>
        </property>
            <!--map类型的属性注入-->
        <property name="maps">
            <map>
                <entry key="k1" value="v1"></entry>
                <entry key="k2" value="v2"></entry>
                <entry key="k3" value="v3"></entry>
            </map>
        </property>
        <!--集合里是对象类型的值-->
        <property name="students">
            <list>
                <ref bean="student1"></ref>
                <ref bean="student2"></ref>
            </list>
        </property>
    </bean>


    <bean id="student1" class="org.learn.spring5.bean.Student">
        <property name="name" value="xiaoming"></property>
        <property name="age" value="15"></property>
    </bean>
    <bean id="student2" class="org.learn.spring5.bean.Student">
        <property name="name" value="xiaohong"></property>
        <property name="age" value="16"></property>
    </bean>
</beans>

第三步:创建测试程序

/**
     * IOC操作Bean管理-注入集合属性
     */
    @Test
    public void test() {

        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        Classes classes = context.getBean("classes", Classes.class);
        classes.test();
    }

 测试程序执行结果:

[zhangsan, lisi, wangwu]
[list1, list2, list3]
{k1=v1, k2=v2, k3=v3}
[Student{name='xiaoming', age=15}, Student{name='xiaohong', age=16}]

5)把集合属性抽取成公共部分

<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                         http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">


    <!--IOC操作Bean管理-提取list集合属性-->
    <!-- 提取list集合属性-->
    <util:list id="list1">
        <value>list1</value>
        <value>list2</value>
        <value>list3</value>
    </util:list>

    <bean id="classes" class="org.learn.spring5.bean.Classes">
        <!--数组类型的属性注入-->
        <property name="student">
            <array>
                <value>zhangsan</value>
                <value>lisi</value>
                <value>wangwu</value>
            </array>

        </property>
        <!--集合类型的属性注入,引入公共的属性-->
        <property name="list" ref="list1"></property>

        <!--map类型的属性注入-->
        <property name="maps">
            <map>
                <entry key="k1" value="v1"></entry>
                <entry key="k2" value="v2"></entry>
                <entry key="k3" value="v3"></entry>
            </map>
        </property>
        <!--集合里是对象类型的值-->
        <property name="students">
            <list>
                <ref bean="student1"></ref>
                <ref bean="student2"></ref>
            </list>
        </property>
    </bean>


    <bean id="student1" class="org.learn.spring5.bean.Student">
        <property name="name" value="xiaoming"></property>
        <property name="age" value="15"></property>
    </bean>
    <bean id="student2" class="org.learn.spring5.bean.Student">
        <property name="name" value="xiaohong"></property>
        <property name="age" value="16"></property>
    </bean>
</beans>

IOC操作Bean管理-工厂bean

Spring 有两种类型的Bean,一种是普通bean,另一种是工厂bean(FactoryBbean)

普通bean:在配置文件中定义的类型和返回类型一致

工厂bean:在配置文件中定义的类型可以和返回类型不一致

工厂bean的实现步骤

1)创建普通类Student

public class Student {

    private String name;

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

2)创建自定义工厂类并实现接口FactoryBean

import org.springframework.beans.factory.FactoryBean;

public class MyBean implements FactoryBean<Student> {
    //定义返回的bean
    public Student getObject() throws Exception {
        Student student = new Student();
        student.setName("zhangsan");
        return student;
    }

    public Class<?> getObjectType() {
        return null;
    }
}

 3)创建Spring的配置文件

<?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="myBean" class="MyBean"></bean>
</beans>

4)创建测试类

  /**
     * IOC操作Bean管理-工厂bean
     */
    @Test
    public void test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
        Student student = context.getBean("myBean", Student.class);
        System.out.println(student);
    }

测试程序执行结果:

Student@23d2a7e8

以上就是对Spring的Bean管理具体的一些实现进行讲解,包括了bean的对象如何创建和属性如何注入的,以及工厂bean是如何创建和创建的。

具体源码可访问我的码云,下载完整源码。

猜你喜欢

转载自blog.csdn.net/java_cxrs/article/details/108289664