• Spring--IOC&&基于XML管理bean


    IOC容器

    IOC思想

    IOC:Inversion of Control 即反转控制

    1. 获取资源的传统方式
      自己做饭:买菜、洗菜、择菜、改刀、炒菜,全过程参与,费时费力,必须清楚了解资源创建整个过程中的全部细节且熟练掌握。
      在应用程序中的组件需要获取资源时,传统的方式是组件主动的从容器中获取所需要的资源,在这样的模式下开发人员往往需要知道在具体容器中特定资源的获取方式,增加了学习成本,同时降低了开发效率。

    2. 反转控制方式获取资源
      点外卖:下单、等、吃,省时省力,不必关心资源创建过程的所有细节。
      反转控制的思想完全颠覆了应用程序组件获取资源的传统方式:反转了资源的获取方向--------改由容器主动的将资源推送给需要的组件,开发人员不需要知道容路是如何创建资源对象的,只需要提供接收资源的方式即可,极大的降低了学习成本,提高了开发的效率。这种行为也称为查找的被动开式。

    3. DI
      Dl: Dependency Injection,翻译过来是依赖注入。
      DI是IOC 的另一种表述方式:即组件以一些预先定义好的方式(例如:setter 方法)接受来自于容器的资源注入。相对于IOC而言,这种表述更直接。

    所以结论是:IOC就是一种反转控制的思想,而DI是对IOC的一种具体实现

    IOC容器在Spring中的实现

    Spring的IOC容器就是IOC思想的一个落地的产品的实现。IOC容器中管理的组件也叫bean,在创建bean之前,首先需要创建IOC容器。Spring提供了IOC容器的两种实现方式

    BeanFactory

    这是IOC容器的基本实现,是Spring内部使用的接口,面向Spring本身,不提供给开发人员使用

    ApplicationContext

    BeanFactory的子接口,提供了更多高级特性。面向Spring的使用者,几乎所有场合都使用ApplicationContext而不是底层的BeanFactory

    ApplicationContext的主要实现类

    在这里插入图片描述

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

    基于XML管理bean

    实验一:入门案例

    1. 创建Maven Module
    2. 引入依赖
      pom.xml
        <dependencies>
    
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-contextartifactId>
                <version>5.3.1version>
            dependency>
    
            <dependency>
                <groupId>junitgroupId>
                <artifactId>junitartifactId>
                <version>4.13.2version>
                <scope>testscope>
            dependency>
        dependencies>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 创建HelloWorld
    package com.bijing.spring.pojo;
    
    /**
     * @author 毕晶
     * @date 2022/11/11 14:50
     */
    public class HelloWorld {
        public void sayHello(){
            System.out.println("hello,spring");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. 创建Spring的配置文件
      在这里插入图片描述

    2. 在Spring的配置文件中配置bean
      application.xml

    
    <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="helloworld" class="com.bijing.spring.pojo.HelloWorld">bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. 创建测试类测试
    package com.bijing.spring.test;
    
    import com.bijing.spring.pojo.HelloWorld;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @author 毕晶
     * @date 2022/11/11 14:56
     */
    public class HelloWorldTest {
        @Test
        public void testHelloWorld(){
            //获取IOC容器
            ApplicationContext ioc = new ClassPathXmlApplicationContext("application.xml");
            //获取IOC容器中的bean
            HelloWorld helloworld = (HelloWorld) ioc.getBean("helloworld");
            helloworld.sayHello();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    实验二:获取bean

    1. 方式一:根据id获取
      由于 id 属性指定了 bean 的唯一标识,所以根据 bean 标签的 id 属性可以精确获取到一个组件对象。 上个实验中我们使用的就是这种方式。
    2. 方式二:根据类型获取
    @Test
    public void testHelloWorld(){
        ApplicationContext ac = new
    ClassPathXmlApplicationContext("applicationContext.xml");
        HelloWorld bean = ac.getBean(HelloWorld.class);
        bean.sayHello();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 方式三:根据id和类型
    @Test
    public void testHelloWorld(){
        ApplicationContext ac = new
    ClassPathXmlApplicationContext("applicationContext.xml");
        HelloWorld bean = ac.getBean("helloworld", HelloWorld.class);
        bean.sayHello();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    1. 注意:注意:根据类型获取bean时,要求IOC中有且只有一个类型匹配的bean;若没有一个类型匹配的bean,也会抛出异常
    2. 拓展

    如果组件类实现了接口,根据接口类型可以获取bean吗
    可以,前提是bean唯一

            //此时Student实现了Person接口,组件类是Student,所以编译类型是Person,运行类型是Student
            Person person = ioc.getBean(Person.class);
            System.out.println(person.getClass());//class com.bijing.spring.pojo.Student
    
    • 1
    • 2
    • 3

    如果一个接口有多个实现类,这些实现类都配置了bean,根据接口类型可以获取bean吗
    不行,因为bean不唯一
    此时,因为Person的实现类有多个,不知道用哪个实现类的bean
    7. 结论
    根据类型来获取bean时,在满足bean唯一的前提下,其实只是看:对象instanceof指定的类型 的返回结果,只要是true就可以认为和类型匹配,就能够获取到。即通过bean的类型,bean所继承的类的类型,bean所实现的接口类型都可以获取bean

    实验三:依赖注入之setter注入

    1. 创建学生类Student
    2. 配置bean时为属性赋值
        <bean id="studentTwo" class="com.bijing.spring.pojo.Student">
            
            <property name="sid" value="1001">property>
            <property name="sname" value="张三">property>
            <property name="age" value="23">property>
            <property name="gender" value="">property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 测试
        @Test
        public void testDI() {
            //获取IOC容器
            ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc.xml");
            //获取bean
            Student studentTwo = ioc.getBean("studentTwo", Student.class);
            System.out.println(studentTwo);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    实验四:依赖注入之构造器注入

    1. 在Student类中添加有参构造器
    2. 配置bean
        
        <bean id="studentThree" class="com.bijing.spring.pojo.Student">
            <constructor-arg value="1002">constructor-arg>
            <constructor-arg value="李四">constructor-arg>
            <constructor-arg value="24" name="age">constructor-arg>
            <constructor-arg value="">constructor-arg>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    1. 测试
            Student studentThree = ioc.getBean("studentThree", Student.class);
            System.out.println(studentThree);
    
    • 1
    • 2

    实验五:特殊值处理

    1. 字面量赋值
    什么是字面量?
    int a=10;
    声明一个变量a,初始化为10,此时a就不代表字母a了,而是作为一个变量的名字。当我们引用a的时候,我们实际拿到的值是10
    如果a是带引号的:'a',那么它现在不是一个变量,它就是代表a这个字母,这就是字面量。
    
    • 1
    • 2
    • 3
    • 4
    1. null值
        
        <bean id="studentFour" class="com.bijing.spring.pojo.Student">
            <property name="sid" value="1003">property>
            <property name="sname" value="王五">property>
            <property name="gender">
                <null>null>
            property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. xml实体
        
        <bean id="studentFour" class="com.bijing.spring.pojo.Student">
            <property name="sid" value="1003">property>
            <property name="sname" value="<王五>">property>
            <property name="gender">
                <null>null>
            property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. CDATA节
        
        <bean id="studentFour" class="com.bijing.spring.pojo.Student">
            <property name="sid" value="1003">property>
            
            <property name="sname">
                <value>]]>value>
            property>
            <property name="gender">
                <null>null>
            property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    实验六:为类类型属性赋值

    1. 创建班级类Clazz
    package com.bijing.spring.pojo;
    
    /**
     * @author 毕晶
     * @date 2022/11/11 19:27
     */
    public class Clazz {
        private Integer cid;
        private String cname;
    
        public Clazz(Integer cid, String cname) {
            this.cid = cid;
            this.cname = cname;
        }
    
        public Clazz() {
        }
    
        public Integer getCid() {
            return cid;
        }
    
        public void setCid(Integer cid) {
            this.cid = cid;
        }
    
        public String getCname() {
            return cname;
        }
    
        public void setCname(String cname) {
            this.cname = cname;
        }
    
        @Override
        public String toString() {
            return "Clazz{" +
                    "cid=" + cid +
                    ", cname='" + cname + '\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    1. 修改Student类
    package com.bijing.spring.pojo;
    
    /**
     * @author 毕晶
     * @date 2022/11/11 15:09
     */
    public class Student implements Person {
        private Integer sid;
        private String sname;
        private Integer age;
        private String gender;
        private Clazz clazz;
    
        public Student() {
        }
    
        public Student(Integer sid, String sname, Integer age, String gender) {
            this.sid = sid;
            this.sname = sname;
            this.age = age;
            this.gender = gender;
        }
    
        public Integer getSid() {
            return sid;
        }
    
        public void setSid(Integer sid) {
            this.sid = sid;
        }
    
        public String getSname() {
            return sname;
        }
    
        public void setSname(String sname) {
            this.sname = sname;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getGender() {
            return gender;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public Clazz getClazz() {
            return clazz;
        }
    
        public void setClazz(Clazz clazz) {
            this.clazz = clazz;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "sid=" + sid +
                    ", sname='" + sname + '\'' +
                    ", age=" + age +
                    ", gender='" + gender + '\'' +
                    ", clazz=" + clazz +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    1. 方式一:引用外部已声明的bean
        
        <bean id="studentFive" class="com.bijing.spring.pojo.Student">
            <property name="sid" value="1004">property>
            <property name="sname" value="赵六">property>
            <property name="age" value="26">property>
            <property name="gender" value="">property>
            <property name="clazz" ref="clazzOne">property>
        bean>
        <bean id="clazzOne" class="com.bijing.spring.pojo.Clazz">
            <property name="cid" value="1111">property>
            <property name="cname" value="三年一班">property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. 方式二:内部bean
    
        
        <bean id="studentFive" class="com.bijing.spring.pojo.Student">
            <property name="sid" value="1004">property>
            <property name="sname" value="赵六">property>
            <property name="age" value="26">property>
            <property name="gender" value="">property>
            <property name="clazz">
                <bean id="clazzInner" class="com.bijing.spring.pojo.Clazz">
                    <property name="cid" value="1111">property>
                    <property name="cname" value="三年一班">property>
                bean>
            property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 方式三:级联属性赋值
        <bean id="studentFive" class="com.bijing.spring.pojo.Student">
            <property name="sid" value="1004">property>
            <property name="sname" value="赵六">property>
            <property name="age" value="26">property>
            <property name="gender" value="">property>
            
            <property name="clazz" ref="clazzOne">property>
            <property name="clazz.cid" value="1111">property>
            <property name="clazz.cname" value="三年一班">property>
        bean>
        <bean id="clazzOne" class="com.bijing.spring.pojo.Clazz">
            <property name="cid" value="1111">property>
            <property name="cname" value="三年一班">property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    实验七:为数组类型属性赋值

    1. 修改Student类
    package com.bijing.spring.pojo;
    
    import java.util.Arrays;
    
    /**
     * @author 毕晶
     * @date 2022/11/11 15:09
     */
    public class Student implements Person {
        private Integer sid;
        private String sname;
        private Integer age;
        private String gender;
        private String[] hobby;
        private Clazz clazz;
    
    
        public Student() {
        }
    
        public Student(Integer sid, String sname, Integer age, String gender) {
            this.sid = sid;
            this.sname = sname;
            this.age = age;
            this.gender = gender;
        }
    
        public Integer getSid() {
            return sid;
        }
    
        public void setSid(Integer sid) {
            this.sid = sid;
        }
    
        public String getSname() {
            return sname;
        }
    
        public void setSname(String sname) {
            this.sname = sname;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public String getGender() {
            return gender;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public Clazz getClazz() {
            return clazz;
        }
    
        public void setClazz(Clazz clazz) {
            this.clazz = clazz;
        }
    
        public String[] getHobby() {
            return hobby;
        }
    
        public void setHobby(String[] hobby) {
            this.hobby = hobby;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "sid=" + sid +
                    ", sname='" + sname + '\'' +
                    ", age=" + age +
                    ", gender='" + gender + '\'' +
                    ", hobby=" + Arrays.toString(hobby) +
                    ", clazz=" + clazz +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    1. 配置bean
            
            <property name="hobby">
                <array>
                    <value>抽烟value>
                    <value>喝酒value>
                    <value>烫头value>
                    <value>蹦迪value>
                array>
            property>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    实验八:为集合类型属性赋值

    1. 为List集合类型的属性赋值
      通过list标签
    <bean id="clazzOne" class="com.bijing.spring.pojo.Clazz">
            <property name="cid" value="1111">property>
            <property name="cname" value="三年一班">property>
            <property name="students">
                <list>
                    <ref bean="studentOne">ref>
                    <ref bean="studentTwo">ref>
                    <ref bean="studentThree">ref>
                    <ref bean="studentFour">ref>
                    <ref bean="studentFive">ref>
                    
                    <bean id="newStudent1" class="com.bijing.spring.pojo.Student">
                        <property name="sid" value="1009">property>
                        <property name="sname" value="新同学">property>
                        <property name="age" value="26">property>
                        <property name="gender" value="">property>
                        <property name="clazz">
                            <bean id="clazzInner" class="com.bijing.spring.pojo.Clazz">
                                <property name="cid" value="1111">property>
                                <property name="cname" value="三年一班">property>
                            bean>
                        property>
                    bean>
                list>
            property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    通过util:list
    需要导入util约束

           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
    
    • 1
    
        <bean id="clazzOne" class="com.bijing.spring.pojo.Clazz">
            <property name="cid" value="1111">property>
            <property name="cname" value="三年一班">property>
            <property name="students" ref="students">
            property>
        bean>
        
        <util:list id="students">
            <ref bean="studentOne">ref>
            <ref bean="studentTwo">ref>
        util:list>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. 为Map集合类型的属性赋值
    //Student增加下面属性
        private Map<String, Teacher> teacherMap;
    
    • 1
    • 2
     <bean id="studentFive" class="com.bijing.spring.pojo.Student">
            <property name="sid" value="1004">property>
            <property name="sname" value="赵六">property>
            <property name="age" value="26">property>
            <property name="gender" value="">property>
            <property name="clazz">
                <bean id="clazzInner" class="com.bijing.spring.pojo.Clazz">
                    <property name="cid" value="1111">property>
                    <property name="cname" value="三年一班">property>
                bean>
            property>
            
            <property name="hobby">
                <array>
                    <value>抽烟value>
                    <value>喝酒value>
                    <value>烫头value>
                    <value>蹦迪value>
                array>
            property>
            
            
            
            
            
            
            
            <property name="teacherMap" ref="teachers">property>
        bean>
        
        <bean id="teacherOne" class="com.bijing.spring.pojo.Teacher">
            <property name="tid" value="10086">property>
            <property name="tname" value="大宝">property>
        bean>
        <bean id="teacherTwo" class="com.bijing.spring.pojo.Teacher">
            <property name="tid" value="10087">property>
            <property name="tname" value="小宝">property>
        bean>
    
        <util:map id="teachers">
            <entry key="10086" value-ref="teacherOne">entry>
            <entry key="10087" value-ref="teacherTwo">entry>
        util:map>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    1. 引用集合类型的bean
      引入util约束,使用util: list、util: map标签,具体使用见上面

    实验九:p命名空间

    引入约束p,应该是指property

           xmlns:p="http://www.springframework.org/schema/p"
    
    • 1
    
        <bean id="studentSix" class="com.bijing.spring.pojo.Student"
              p:sid="1005" p:sname="小明" p:teacherMap-ref="teachers">bean>
    
    • 1
    • 2
    • 3

    实验十:引入外部属性文件

    jdbc为例

    1. 加入依赖
      pom.xml
          
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>8.0.30version>
            dependency>
            
            <dependency>
                <groupId>com.alibabagroupId>
                <artifactId>druidartifactId>
                <version>1.0.31version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    1. 创建外部属性文件
      jdbc.properties
    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimeZone=UTC"
    jdbc.username=root
    jdbc.password=root1234
    
    • 1
    • 2
    • 3
    • 4
    1. 引入属性文件
      引入约束context
           xmlns:context="http://www.springframework.org/schema/context"
    
    • 1
        
        <context:property-placeholder location="jdbc.properties"/>
    
    • 1
    • 2
    1. 配置bean
        <bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource">
            <property name="driverClassName" value="${jdbc.driver}">property>
            <property name="url" value="${jdbc.url}">property>
            <property name="username" value="${jdbc.username}">property>
            <property name="password" value="${jdbc.password}">property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. 测试
    public class DataSourceTest {
        @Test
        public void testDataSource() throws SQLException {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-datasource.xml");
            DruidDataSource datasource = ioc.getBean("datasource", DruidDataSource.class);
            DruidPooledConnection connection = datasource.getConnection();
            System.out.println(connection);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    实验十一:bean的作用域

    1. 概念
      在Spring中可以通过配置bean标签的scope来指定bean的作用域范围,各取值含义参如下表
    取值含义创建对象的时机
    singleton(默认)在IOC容器中,这个bean对象始终为单例IOC容器初始化
    prototype这个bean在IOC容器中有多个实例获取bean时

    如果在WebApplicationContext环境下还有另外两个作用域(但不常用)

    取值含义
    request在一个请求范围内有效
    session在一次会话范围内有效
    1. 创建类Student
      就是之前使用的Student类
    2. 配置bean
      
        <bean id="student" class="com.bijing.spring.pojo.Student" scope="prototype">
            <property name="sid" value="1001">property>
            <property name="sname" value="张三">property>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 测试
        @Test
        public void testScope() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-scope.xml");
            Student student1 = ioc.getBean("student", Student.class);
            Student student2 = ioc.getBean("student", Student.class);
            System.out.println(student1 == student2);//true说明是单例模式创建的student,是同一个对象
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    实验十二:bean的生命周期

    1. 具体的生命周期过程
    • bean对象创建(调用无参构造器)
    • 给bean对象设置属性
    • bean对象初始化之前操作(由bean的前置处理器负责)
    • bean对象初始化(需在配置bean时指定初始化方法)
    • bean对象初始化之后操作(由bean的后置处理器负责)
    • bean对象就绪可以使用
    • bean对象的销毁(需要在配置bean的时候指定销毁方法)
    • IOC容器关闭
    1. 创建类User和MyBeanPostProcessor
    package com.bijing.spring.pojo;
    
    /**
     * @author 毕晶
     * @date 2022/11/11 22:31
     */
    public class User {
        private Integer id;
        private String username;
        private String password;
        private Integer age;
    
        public User() {
            System.out.println("生命周期1:实例化");
        }
    
        public User(Integer id, String username, String password, Integer age) {
            this.id = id;
            this.username = username;
            this.password = password;
            this.age = age;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            System.out.println("生命周期2:依赖注入");
            this.id = id;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    ", age=" + age +
                    '}';
        }
    
        public void initMethod() {
            System.out.println("生命周期3:初始化");
        }
    
        public void destroyMethod() {
            System.out.println("生命周期4:销毁");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    public class MyBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            //此方法在bean的生命周期初始化之前执行
            System.out.println("此方法在bean的生命周期初始化之前执行");
            return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            //此方法在bean的生命周期初始化之后执行
            System.out.println("此方法在bean的生命周期初始化之后执行");
            return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. 配置bean
    
    <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.bijing.spring.pojo.User" init-method="initMethod" destroy-method="destroyMethod">
            <property name="id" value="1">property>
            <property name="username" value="admin">property>
            <property name="password" value="123456">property>
            <property name="age" value="23">property>
        bean>
            
         <bean id="myBeanPostProcessor" class="com.bijing.spring.process.MyBeanPostProcessor">bean>
    
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 测试
    package com.bijing.spring.test;
    
    import com.bijing.spring.pojo.User;
    import org.junit.Test;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @author 毕晶
     * @date 2022/11/11 22:43
     */
    public class LifeCycleTest {
        /**
         * 1.实例化
         * 2.依赖注入
         * 3.初始化 要通过bean标签的init-method属性指定方法
         * 4.IOC容器关闭时销毁 要通过bean标签的destroy-method属性指定方法
         *      
         * 注意:
         * 若bean的作用域是单例时,生命周期的前三个步骤会在获取IOC容器时执行
         * 若bean的作用域是多例时,生命周期的前三个步骤会在获取bean时执行,销毁步骤不由ioc控制了
         */
        @Test
        public void testLifeCycle() {
            //ConfigurableApplicationContext是ApplicationContext的子接口,其中拓展了刷新和关闭容器的方法
            //注意:1.如果是bean对象是单例模式获取的,则生命周期前三个步骤已经完成,即ioc容器创建的时候bean对象就已经创建并完成了初始化
            //    2.如果是多例,destroy步骤不由ioc来控制了,即ioc.close()时销毁方法不执行
            ConfigurableApplicationContext ioc = new ClassPathXmlApplicationContext("spring-lifecycle.xml");
            User user = ioc.getBean(User.class);
            System.out.println(user);
            //ApplicationContext没有close方法
            ioc.close();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    1. bean的后置处理器
      bean的后置处理器会在生命周期的初始化前后添加额外的操作,需要实现BeanPostProcessor接口,且配置到IOC容器中,需要注意的是,bean后置处理器不是单独针对某—个bean生效,而是 针对IOC容器中所有bean都会执行

    创建bean的后置处理器

    package com.bijing.spring.pojo.com.bijing.spring.process;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    /**
     * @author 毕晶
     * @date 2022/11/12 10:17
     */
    public class MyBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            //此方法在bean的生命周期初始化之前执行
            System.out.println("此方法在bean的生命周期初始化之前执行");
            return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            //此方法在bean的生命周期初始化之后执行
            System.out.println("此方法在bean的生命周期初始化之后执行");
            return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    配置bean的后置处理器

        <bean id="myBeanPostProcessor" class="com.bijing.spring.pojo.com.bijing.spring.process.MyBeanPostProcessor">bean>
    
    • 1

    实验十三:FactoryBean

    1. 简介
      Spring中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean,即FactoryBean,这两种Bean都被容器管理,但工厂Bean跟普通Bean不同,其返回的对象不是指定类的一个实例,其返回的是该FactoryBean的getObject方法所返回的对象。通过这种机制,Spring可以帮我们把复杂组件创建的详细过程和繁琐细节都屏蔽起来,只把最简洁的使用界面展示给我们。

    2. 创建类UserFactoryBean

    package com.bijing.spring.factory;
    
    import com.bijing.spring.pojo.User;
    import org.springframework.beans.factory.FactoryBean;
    
    /**
     * @author 毕晶
     * @date 2022/11/12 10:35
     */
    public class UserFactoryBean implements FactoryBean<User> {
        @Override
        public User getObject() throws Exception {
            return new User();
        }
    
        @Override
        public Class<?> getObjectType() {
            return User.class;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    1. 配置bean
        <bean class="com.bijing.spring.factory.UserFactoryBean">bean>
    
    • 1
    1. 测试
    public class FactoryBeanTest {
        @Test
        public void testFactoryBean() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-factory.xml");
            User user = ioc.getBean(User.class);
            System.out.println(user);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    实验十四:基于xml的自动装配

    自动装配:
    根据指定的策略,在IOC容器中匹配某一个bean,自动为指定的bean中所依赖的类类型或者接口类型属性赋值

    1. 场景模拟
      创建UserController
    public class UserController {
        private UserService userService;
    
        //UserService会变动,不要直接写死,使用set和get方法有利于改动
        public UserService getUserService() {
            return userService;
        }
    
        public void setUserService(UserService userService) {
            this.userService = userService;
        }
    
        public void saveUser() {
            userService.saveUser();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    1. 配置bean
    
    <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="userController" class="com.bijing.spring.controller.UserController" autowire="byType">
            
        bean>
        <bean id="userService" class="com.bijing.spring.service.impl.UserServiceIml" autowire="byType">
            
        bean>
        <bean id="userDao" class="com.bijing.spring.dao.impl.UserDaoImpl">bean>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 测试
    package com.bijing.spring.test;
    
    import com.bijing.spring.controller.UserController;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @author 毕晶
     * @date 2022/11/12 17:13
     */
    public class AutowireByXmlTest {
    
        /**
         * 自动装配:
         * 根据指定的策略,在IOC容器中匹配某个bean,自动为bean中的类类型的属性或者接口类型属性赋值
         * 可以通过bean标签中autowire属性设置自动装配的策略
         * 自动装配策略:
         * #no,default表示不装配,即bean 中的属性不会自动匹配某个bean为属性赋值,此时属性使用默认值
         * #byType:根据要赋值的属性的类型,在IOC容器中匹配某个bean,为属性赋值
         * 注意:1.若通过类型没有找到任何一个类型匹配的bean,此时不匹配,属性使用默认值
         * 2.若通过类型找到了多个类型匹配的bean,此时会抛出异常:
         * 总结:当使用byType实现自动装配时,IOC容器中有且只有一个类型匹配的bean能够为属性赋值
         * #byName:将要赋值的属性的属性名作为bean的id在IOC容器中匹配某个bean为属性赋值
         * 当类型匹配的bean有多个时,此时可以使用byName实现自动装配
         */
        @Test
        public void testAutowireByXml() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-autowire-xml.xml");
            UserController userController = ioc.getBean(UserController.class);
            userController.saveUser();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
  • 相关阅读:
    神经网络中epoch、batch、batchsize区别
    外贸增长背后的跨境电商转型路径
    SpringBoot
    用Qt自制一个小闹钟
    Apache Knox 2.0.0使用
    CSDN Q: “这段代码算是在STC89C52RC51单片机上完成PWM呼吸灯了吗?“
    论文阅读:基于隐马尔可夫模型的蛋白质多序列比对方法研究
    28.Python面向对象(一)【类:创建类&实例对象,私有属性,类里面的方法,类属性CRUD,常用内置类属性】
    南卡对比评测明基护眼灯,2022双十一哪一款护眼台灯更值得入手
    RabbitMQ介绍
  • 原文地址:https://blog.csdn.net/weixin_43903745/article/details/127353502