Spring5学习笔记之IOC操作基于XML方式实现

Bean管理

1、什么是Bean管理?

Bean管理指的是两个操作:

  • Spring创建对象
  • Spirng注入属性

2、Bean管理操作有两种方式.

  • (1)基于xml配置文件方式实现
  • (2)基于注解方式实现

基于XML方式创建对象

xml中的配置代码:

    <!--配置user对象创建-->
    <bean id="user" class="com.atschool.pojo.User"></bean>
  • 在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建。
  • 在bean标签有很多属性,介绍常用的属性:id 属性,代表唯一标识;class 属性,类的全类名。
  • 创建对象时候,默认执行无参构造器完成对象创建

基于XML方式注入属性

一、 使用set方法注入

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

package com.atschool.pojo;

/**
 * Description:
 * Author:江洋大盗
 * Date:2021/1/24 19:41
 */
public class User {
    
    
    //1.定义属性
    private String name;
    private int age;

    //2.生成对应的set方法
    public void setName(String name) {
    
    
        this.name = name;
    }

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

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

(2)在spring配置文件配置对象创建,配置属性注入。

    <!--配置user对象创建-->
    <bean id="user" class="com.atschool.pojo.User">
        <!--使用property标签完成属性注入
        name:类里面属性名称
        value:向属性注入的值-->
        <property name="name" value="微若尘埃璨若星辰"></property>
        <property name="age" value="20"></property>
    </bean>

二、使用有参构造器注入属性

(1)创建类,定义属性,创建属性对应有参构造器

package com.atschool.pojo;

/**
 * Description:
 * Author:江洋大盗
 * Date:2021/1/24 19:41
 */
public class User {
    
    
    //1.定义属性
    private String name;
    private int age;

    public User(String name, int age) {
    
    
        this.name = name;
        this.age = age;
    }

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

(2)在spring配置文件中进行配置

    <!--配置user对象创建-->
    <bean id="user" class="com.atschool.pojo.User">
        <!--3.使用有参构造器注入属性-->
        <constructor-arg name="name" value="微若尘埃粲若星辰"></constructor-arg>
        <constructor-arg name="age" value="20"></constructor-arg>
    </bean>

三、P名称空间注入属性(了解)

(1)添加p名称空间在配置文件中

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

(2)进行属性注入,在bean标签里面进行操作

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

    <!--属性注入,set方法注入-->
    <bean id="user" class="com.atschool.pojo.User" p:name="微若尘埃粲若星辰" p:age="20">
    </bean>
</beans>

基于XML注入其他类型属性

一、字面量

(1) null值

    <!--使用null标签注入null值-->
        <property name="name">
            <null/>
        </property>

(2)属性中包含特殊符号

解决方法一:将特殊字符转义,&lt ;&gt ;
解决方式二:把带特殊符号内容写到CDATA

        <property name="name">
            <!--注意CDATA的写法-->
            <value><![CDATA[<<微若尘埃璨若星辰>>]]></value>
        </property>

二、注入属性——外部bean

(1)创建两个类service类和dao类
(2)在service调用dao里面的方法

package com.atschool.pojo;

/**
 * Description:
 * Author:江洋大盗
 * Date:2021/1/24 20:46
 */
public class Dao {
    
    
    public void delete() {
    
    
        System.out.println("delete方法被调用了---------");
    }
}

package com.atschool.pojo;

/**
 * Description:
 * Author:江洋大盗
 * Date:2021/1/24 20:45
 */
public class Service {
    
    
    //1.创建外部bean属性
    private Dao dao;

    //2.生成对应的set方法
    public void setDao(Dao dao) {
    
    
        this.dao = dao;
    }

    public void add() {
    
    
        dao.delete();
        System.out.println("add方法被调用了-----");
    }
}

(3)在spring配置文件中进行配置

	<!--外部bean-->
    <!--1 service和dao对象创建-->
    <bean id="service" class="com.atschool.pojo.Service">
        <!--注入userDao对象
        name属性:类里面属性名称
        ref属性:创建Dao对象bean标签id值-->
        <property name="dao" ref="dao"></property>
    </bean>
    <bean id="dao" class="com.atschool.pojo.Dao"></bean>

三、注入属性——内部bean

(1)一对多关系:部门和员工一个部门有多个员工,一个员工属于一个部门,部门是一,员工是多。
(2)在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示。

package com.atschool.pojo;

/**
 * Description:部门类
 * Author:江洋大盗
 * Date:2021/1/24 20:58
 */
public class Dept {
    
    
    private String name;//部门名称

    //生成set方法
    public void setName(String name) {
    
    
        this.name = name;
    }

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

在spring配置文件中进行配置:

    <!--内部bean-->
    <bean id="emp" class="com.atschool.pojo.Emp">
        <!--设置两个普通属性-->
        <property name="name" value="小明"></property>
        <property name="gender" value=""></property>
        <!--设置对象类型属性-->
        <property name="dept">
            <bean class="com.atschool.pojo.Dept">
                <property name="name" value="IT技术部"></property>
            </bean>
        </property>
    </bean>

四、级联赋值

写法一:

    <!--级联赋值-->
    <bean id="emp" class="com.atschool.pojo.Emp">
        <!--设置两个普通属性-->
        <property name="name" value="小明"></property>
        <property name="gender" value=""></property>
        <!--级联赋值-->
        <property name="dept" ref="dept"></property>
    </bean>

    <bean id="dept" class="com.atschool.pojo.Dept">
        <property name="name" value="IT技术部"></property>
    </bean>

写法二:

    //1.生成dept的get方法
    public Dept getDept() {
    
    
        return dept;
    }

在spring配置文件中进行配置:

    <!--级联赋值-->
    <bean id="emp" class="com.atschool.pojo.Emp">
        <!--设置两个普通属性-->
        <property name="name" value="小明"></property>
        <property name="gender" value=""></property>
        <!--级联赋值-->
        <property name="dept" ref="dept"></property>
        <property name="dept.name" value="IT技术部"></property>
    </bean>

    <bean id="dept" class="com.atschool.pojo.Dept">
    </bean>

基于XML注入集合类型属性

注入集合类型属性

  1. 注入数组类型属性
  2. 注入List集合类型属性
  3. 注入Map集合类型属性
  4. 注入Set集合类型属性

(1)创建类,定义数组、list、map、set类型属性,生成对应set方法:

package com.atschool.pojo;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Description:
 * Author:江洋大盗
 * Date:2021/1/24 21:22
 */
public class Student {
    
    
    //1 数组类型属性
    private String[] courses;
    // 2 list集合类型属性
    private List<String> list;
    // 3 map集合类型属性
    private Map<String, String> maps;
    // 4 set集合类型属性
    private Set<String> sets;

    public void setCourses(String[] courses) {
    
    
        this.courses = courses;
    }

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

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

    public void setSets(Set<String> sets) {
    
    
        this.sets = sets;
    }

    @Override
    public String toString() {
    
    
        return "Student{" +
                "courses=" + Arrays.toString(courses) +
                ", list=" + list +
                ", maps=" + maps +
                ", sets=" + sets +
                '}';
    }
}

(2)在spring配置文件进行配置

    <!--1 集合类型属性注入-->
    <bean id="student" class="com.atschool.pojo.Student">
        <!--数组类型属性注入-->
        <property name="courses">
            <array>
                <value>JAVA</value>
                <value>Spring</value>
            </array>
        </property>
        <!--list类型属性注入-->
        <property name="list">
            <list>
                <value>JAVA</value>
                <value>Spring</value>
            </list>
        </property>
        <!--map类型属性注入-->
        <property name="maps">
            <map>
                <entry key="JAVA" value="java"></entry>
                <entry key="SPRING" value="spring"></entry>
            </map>
        </property>
        <!--set类型属性注入-->
        <property name="sets">
            <set>
                <value>JAVA</value>
                <value>Spring</value>
            </set>
        </property>
    </bean>

在集合里面设置对象类型值

package com.atschool.bean;

/**
 * Description:
 * Author:江洋大盗
 * Date:2021/1/24 21:59
 */
public class Course {
    
    
    private String name;

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

    @Override
    public String toString() {
    
    
        return "Course{" +
                "name='" + name + '\'' +
                '}';
    }
}
package com.atschool.bean;

import java.util.List;

/**
 * Description:
 * Author:江洋大盗
 * Date:2021/1/24 22:00
 */
public class CourseList {
    
    
    private List<Course> courseList;

    public void setCourseList(List<Course> courseList) {
    
    
        this.courseList = courseList;
    }

    @Override
    public String toString() {
    
    
        return "CourseList{" +
                "courseList=" + courseList +
                '}';
    }
}

在spring配置文件进行配置

    <!--创建多个course对象-->
    <bean id="course1" class="com.atschool.bean.Course">
        <property name="name" value="JAVA"></property>
    </bean>
    <bean id="course2" class="com.atschool.bean.Course">
        <property name="name" value="Spring"></property>
    </bean>
    <!--注入list集合类型,值是对象-->
    <bean id="courseList" class="com.atschool.bean.CourseList">
        <property name="courseList">
            <list>
                <ref bean="course1"></ref>
                <ref bean="course2"></ref>
            </list>
        </property>
    </bean>

把集合注入部分公共化

(1)在spring配置文件中引入名称空间util

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

(2)使用util标签完成list集合注入提取

    <!--1 提取list集合类型属性注入-->
    <util:list id="list">
        <value>JAVA</value>
        <value>Spring</value>
    </util:list>
        <!--2 提取list集合类型属性注入使用-->
        <property name="list">
            <ref bean="list"></ref>
        </property>

FactoryBean

  1. Spring有两种类型bean,一种普通bean(上述介绍的都是普通bean),另外一种工厂bean(FactoryBean)。
  2. 普通bean:在配置文件中定义bean类型就是返回类型。
  3. 工厂bean:在配置文件定义bean类型可以和返回类型不一样。

第一步: 创建类,让这个类作为工厂bean,实现接口FactoryBean。
第二步 :实现接口里面的方法,在实现的方法中定义返回的bean类型

package com.atschool.bean;

import org.springframework.beans.factory.FactoryBean;

/**
 * Description:
 * Author:江洋大盗
 * Date:2021/1/24 22:17
 */
public class MyBean implements FactoryBean<Course> {
    
    
    @Override
    public Course getObject() throws Exception {
    
    
        Course course = new Course();
        course.setName("java架构师直通车");
        return course;
    }

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

    @Override
    public boolean isSingleton() {
    
    
        return false;
    }
}

配置文件:

<bean id="myBean" class="com.atschool.bean.MyBean"></bean>

验证:

    @Test
    public void test06(){
    
    
        ApplicationContext context =
                new ClassPathXmlApplicationContext("bean3.xml");
        Course course = context.getBean("myBean", Course.class);
        System.out.println(course);
    }

输出结果:
验证结果

bean作用域

默认情况

在Spring里面,默认情况下,bean是单实例对象:
测试
可见上述代码中。dog1和dog2的地址一样,证明默认情况下,bean确实是单实例对象。

如何设置单实例还是多实例

(1)在spring配置文件bean标签里面有属性(scope)用于设置单实例还是多实例。
(2)scope属性值:第一个值,默认值,singleton,表示是单实例对象;第二个值prototype,表示是多实例对象

    <bean id="dog" class="com.atschool.bean.Dog" scope="prototype"></bean>

测试可见将scope属性设置为prototype后,dog1和dog2的输出地址不一样。

singleton和prototype区别

  • singleton单实例,prototype多实例
  • 设置scope值是singleton时候,加载spring配置文件时候就会创建单实例对象。
  • 设置scope值是prototype时候,不是在加载spring配置文件时候创建对象,在调用getBean方法时候创建多实例对象。

bean生命周期

bean生命周期简要概述

  1. 通过构造器创建bean实例(无参数构造)
  2. 为bean的属性设置值和对其他bean引用(调用set方法)
  3. 调用bean的初始化的方法(需要进行配置初始化的方法)
  4. bean可以使用了(对象获取到了)
  5. 当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)

演示bean生命周期

package com.atschool.bean;

/**
 * Description:
 * Author:江洋大盗
 * Date:2021/1/24 22:26
 */
public class Dog {
    
    
    private String name;

    public Dog() {
    
    
        System.out.println("第一步 执行无参数构造创建bean实例");
    }

    public void setName(String name) {
    
    
        this.name = name;
        System.out.println("第二步 调用set方法设置属性值");
    }

    //创建执行的初始化的方法
    public void initMethode() {
    
    
        System.out.println("第三步 执行初始化的方法");
    }

    //创建销毁的方法
    public void destroyMethode() {
    
    
        System.out.println("第五步 执行销毁的方法");
    }
}

配置文件

    <!--注:这里请将scope属性设置为单例模式,否则销毁方法不执行-->
    <bean id="dog" class="com.atschool.bean.Dog" init-method="initMethode"
          destroy-method="destroyMethode">
        <property name="name" value="旺财">
        </property>
    </bean>

测试代码

    @Test
    public void test07(){
    
    
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");
        Dog dog = context.getBean("dog", Dog.class);
        System.out.println("第四步获取创建bean实例对象");
        System.out.println(dog);
        //手动让bean实例销毁
        context.close();
    }

测试结果
测试结果

添加后置处理器

(1)创建类,实现接口BeanPostProcessor,创建后置处理器

package com.atschool.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * Description:
 * Author:江洋大盗
 * Date:2021/1/24 22:54
 */
public class MyBeanPost implements BeanPostProcessor {
    
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    
    
        System.out.println("初始化之前执行的方法");
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    
    
        System.out.println("初始化之后执行的方法");
        return null;
    }
}
    <!--配置后置处理器-->
    <bean id="myBeanPost" class="com.atschool.bean.MyBeanPost">
    </bean>

测试代码:

    @Test
    public void test07(){
    
    
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("bean1.xml");
        Dog dog = context.getBean("dog", Dog.class);
        System.out.println("第四步获取创建bean实例对象");
        System.out.println(dog);
        //手动让bean实例销毁
        context.close();
    }

执行结果:
测试结果

XML自动装配

什么是自动装配

根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入。

演示自动装配过程

bean标签属性autowire,配置自动装配autowire属性常用两个值:byName根据属性名称注入,注入值bean的id值和类属性名称一样;byType根据属性类型注入。

(1)根据属性名称自动注入:

    <!--根据属性名称自动装配-->
    <bean id="service" class="com.atschool.pojo.Service" autowire="byName">
<!--<property name="dao" ref="dao">-->
<!-- </property>-->
    </bean>
    <bean id="dao" class="com.atschool.pojo.Dao">
    </bean>

(2)根据属性类型自动注入

    <bean id="service" class="com.atschool.pojo.Service" autowire="byType">
<!--<property name="dao" ref="dao">-->
<!--</property>-->
    </bean>
    <bean id="dao" class="com.atschool.pojo.Dao">
    </bean>

外部属性文件

引入外部属性文件配置数据库连接池
(1)创建外部属性文件,properties格式文件,写数据库信息
配置文件
(2)把外部properties属性文件引入到spring配置文件中

引入context名称空间:

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

配置具体信息:

    <!--引入外部属性文件-->
    <context:property-placeholder location="classpath:jdbc.properties" />
    <!--配置连接池-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${driverName}" />
        <property name="url" value="${url}" />
        <property name="username" value="${userName}" />
        <property name="password" value="${password}" />
    </bean>

结语

只要能收获甜蜜,荆棘丛中也有蜜蜂忙碌的身影,未来的你一定会感谢现在努力的自己。

猜你喜欢

转载自blog.csdn.net/m0_52099927/article/details/113096079