Spring5-IOC容器基于XML配置管理

IOC容器

1、什么是IOC
  • 把对象的创建以及对象之间的相互调用过程交给spring进行管理
  • 其目的是为了降低耦合度
2、IOC底层技术
  • xml解析、工厂模式、反射
3、spring提供的IOC容器实现的两种方式(接口)
  • BeanFactory接口
    1、该接口是spring内部接口所使用,不提供给开发人员使用
    2、此方式创建IOC容器,在加载配置文件时不会创建对象,在获取对象时才会创建
  • ApplicationContext接口(推荐)
    1、是BeanFactory接口的子接口,有更多的功能,提供给开发人员使用
    2、加载配置文件时就会创建对象

IOC-bean管理

  • IOC容器bean管理操作:创建对象、注入属性
1、spring创建对象
<!-- 配置创建对象 -->
<bean id="user" class="com.spring.one.User"></bean>
2、spring注入属性
  • 属性set方法

使用property标签初始化的属性,必须有set公共方法

// 创建User类
public class User {
    private String name;

    public void setName(String name) {
        this.name = name;
    }
}
<bean id="user" class="com.spring.one.User">
        <!-- 使用property标签
             name:属性名称
             value:属性注入的值
         -->
        <property name="name" value="macgrady"></property>
</bean>
  • 有参构造器

使用constructor-arg标签初始化属性,该类必须拥有对应的有参构造器

public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }
}
<bean id="user" class="com.spring.one.User">
        <!-- 使用constructor-arg标签 -->
        <constructor-arg name="name" value="macgrady"></constructor-arg>
</bean>
  • 为属性注入null或特殊字符
<bean id="user" class="com.spring.one.User">
        <!-- 注入空 -->
        <property name="name">
            <null/>
        </property>

        <!-- 注入特殊符号 >@3< -->
        <!-- <![CDATA[数据]]> -->
        <property name="address">
            <value><![CDATA[>@3<]]></value>
        </property>
</bean>
  • 注入属性 - 外部bean(属性指向其他类对象)
public class User {
    private String name;
    private Animal animal;

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

    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}

class Animal {
    private String name;
    private int age;

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

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

class Cat extends Animal { 
}
<bean id="user" class="com.spring.one.User">
        <property name="name" value="tom"></property>
        <!-- 属性指向另一个类的对象
             使用property标签中ref属性,指向bean外部的bean对象
        -->
        <property name="animal" ref="cat"></property>
    </bean>
    <!-- 配置Cat类对象 -->
    <bean id="cat" class="com.spring.one.Cat">
        <property name="name" value="补丁"></property>
        <property name="age" value="2"></property>
</bean>
  • 注入属性 - 内部bean

在property属性标签内部创建bean标签

<bean id="user" class="com.spring.one.User">
        <property name="name" value="tom"></property>
        <property name="animal">
            <!-- 配置Cat类对象 -->
            <bean id="cat" class="com.spring.one.Cat">
                <property name="name" value="补丁"></property>
                <property name="age" value="2"></property>
            </bean>
        </property>
</bean>
  • 注入属性 - 级联赋值
public class User {
    private String name;
    private Cat cat;

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

    public void setAnimal(Cat cat) {
        this.cat = cat;
    }
    // 使用对象.属性的方式进行级联赋值,则该get对象方法必须有
    public Cat getCat() {
        return cat;
    }
}

class Animal {
    private String name;
    private int age;

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

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

class Cat extends Animal {
}
<bean id="user" class="com.spring.one.User">
    <property name="name" value="tom"></property>
    <!-- 可以使用对象.属性的方式进行赋值 -->
    <property name="animal" ref="cat"></property>
    <property name="cat.name" value="小叮当"></property>
    <property name="cat.age" value="3"></property>
</bean>
  • 注入属性 - 数组、集合类型
public class User {
    private String[] hobby;
    private List<String> honor;
    private Map<String,Double> exam;

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

    public void setHonor(List<String> honor) {
        this.honor = honor;
    }

    public void setExam(Map<String, Double> exam) {
        this.exam = exam;
    }
}
<bean id="user" class="com.spring.one.User">
        <!-- 数组类型属性赋值 -->
        <property name="hobby">
            <array>
                <value>打篮球</value>
                <value>写情书</value>
            </array>
        </property>
        <!-- List集合类型属性赋值 -->
        <property name="honor">
            <list>
                <value>2019全国奥数第二名</value>
                <value>青年组自由滑雪全国第三名</value>
            </list>
        </property>
        <!-- Map集合类型属性赋值 -->
        <property name="exam">
            <map>
                <entry key="语文" value="98"></entry>
                <entry key="数学" value="99"></entry>
                <entry key="英语" value="89"></entry>
            </map>
        </property>
</bean>
  • 注入属性 - 集合类型属性包含其他对象类型
public class User {
    private List<Course> courses;

    public void setCourses(List<Course> courses) {
        this.courses = courses;
    }
}

class Course {
    private String name;
    private String teacher;

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

    public void setTeacher(String teacher) {
        this.teacher = teacher;
    }
}
<bean id="user" class="com.spring.one.User">
        <!-- List集合包含对象类型赋值 -->
        <property name="courses">
            <list>
                <ref bean="course_chinese"></ref>
                <ref bean="course_math"></ref>
            </list>
        </property>
</bean>
<bean id="course_chinese" class="com.spring.one.Course">
        <property name="name" value="语文"></property>
        <property name="teacher" value="高明杨"></property>
</bean>
<bean id="course_math" class="com.spring.one.Course">
        <property name="name" value="数学"></property>
        <property name="teacher" value="刘凤山"></property>
</bean>
  • 注入属性 - 公共数据
<!-- 1、引入名称空间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 http://www.springframework.org/schema/util/spring-util.xsd">

    <!-- 2、使用util标签完成list集合配置 -->
    <util:list id="my_list">
        <value>篮球</value>
        <value>足球</value>
        <value>游泳</value>
    </util:list>

    <!-- 提取对象集合 -->
    <util:list id="my_list2">
        <ref bean="course_math"></ref>
        <ref bean="course_chinese"></ref>
    </util:list>

    <bean id="user" class="com.spring.one.User">
        <!-- 3、引入提取出的list集合 -->
        <property name="hobby" ref="my_list"></property>
    </bean>
    <bean id="course_chinese" class="com.spring.one.Course">
        <property name="name" value="语文"></property>
        <property name="teacher" value="高明杨"></property>
    </bean>
    <bean id="course_math" class="com.spring.one.Course">
        <property name="name" value="数学"></property>
        <property name="teacher" value="刘凤山"></property>
    </bean>
3、FactoryBean
  • Spring包括两种bean类型,普通bean类型和工厂bean类型
  • 普通bean类型在配置文件定义的bean类型就是返回值类型
  • 工厂bean类型在配置文件定的类型可以不是返回值类型
  • 工厂bean创建方式:
    1、创建类并实现FactoryBean接口
    2、实现getObject方法,在方法中设置返回值类型
// 定义工厂bean
public class MyFactoryBean implements FactoryBean<User> {
    @Override
    public User getObject() throws Exception {
        User user = new User();
        return user;
    }

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

    @Override
    public boolean isSingleton() {
        return false;
    }
}
<bean id="myFactoryBean" class="com.spring.one.factorybean.MyFactoryBean"></bean>
@Test
public void test() {
    ApplicationContext appContext =
            new ClassPathXmlApplicationContext("bean2.xml");
    User user = appContext.getBean("my_factofy_bean", User.class);
}
4、创建bean的单例和多实例
  • Spring中创建bean对象(getBean方法)默认情况是单例模式
  • 通过配置<bean>标签中的scope属性,可以设置为多实例模式
  • singleton:单实例模式,在加载配置文件时创建对象
  • prototype:多实例模式,在调用getBean方法是创建对象
<bean scope="prototype" id="user" class="com.spring.one.User"></bean>
5、bean生命周期
  • bean对象从创建到销毁流程
    1、通过构造器创建bean对象实例(无参构造)
    2、为bean对象的属性赋值(属性set方法)
    3、调用bean对象的初始化方法(需要配置)
    4、获取到完整的bean对象实例,可以使用
    5、容器关闭时,调用bean对象的销毁方法(需要配置)
public class User {
    private String name;

    public User() {
    }

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

    // 自定义初始化方法
    public void initMethod() {
        System.out.println("初始化方法");
    }

    // 自定义销毁方法
    public void destroyMethod() {
        System.out.println("销毁方法");
    }
}

bean标签中init-method和destory-method属性配置初始化和销毁方法

<!-- bean标签中init-method和destory-method属性配置初始化和销毁方法 -->
    <bean id="user" class="com.spring.one.User" init-method="initMethod" destroy-method="destroyMethod">
        <property name="name" value="tom"></property>
    </bean>
  • 创建并配置后置处理器后(实现BeanPostProcessor接口),将在bean的初始化方法调用前后分别执行前置方法和后置方法
public class MyBeanPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return null;
    }
}

配置后置处理器

<bean id="myBeanPost" class="com.spring.one.MyBeanPost"></bean>
6、操作外部属性文件(properties格式文件)
  • 直接配置数据库连接池参数
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/userDb"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
</bean>
  • 通过properties文件配置

1、创建properties文件

prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/userDb
prop.userName=root
prop.password=root

2、修改配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- 1、引入名称空间context -->
<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 http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 2、引入外部properties文件 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- 3、使用${属性名}的方式配置 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${prop.driverClass}"></property>
        <property name="url" value="${prop.url}"></property>
        <property name="username" value="${prop.userName}"></property>
        <property name="password" value="${prop.password}"></property>
    </bean>
</beans>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容