天天看点

SpringIOC控制反转之XML配置

IOC概念

​ ( Inversion of Control,缩写为 IoC),是面向对象编程中的一种设计原则,可以用来降低计算机代码之间的耦合度。

​ 简单来说Spring中的IOC控制反转就是将对象实例化对象的控制权,由手动的new,转为交给Spring框架通过反射机制,进行对象的实例化。

​ 在Spring入门中我们已经使用了xml配置来控制对象的创建,实现了控制反转。

容器的使用

​ 前面说了控制反转就是将创见对象的控制权由new,转为交给Spring框架通过反射机制,进行对象的实例化,Spring容器进行实例化后会将创建的实例对象放入Spring容器,那么Spring容器到底是什么东西?

概念理解

​ 容器,容器,顾名思义就是用来装东西的;如我们生活中的水杯,水桶、水盆等等,所以我们的Spring容器也是用来装东西的;水杯、水桶用来装水,而我们的Spring容器就是用来装对象实例的。

IOC 容器的体系结构

  • spring容器

    Spring的容器有两个

    1. BeanFactory
    2. ApplicationContext
  • 两者的关系
    SpringIOC控制反转之XML配置

    可以看出,他们两个都是接口,并且ApplicationContext是BeanFactory的子接口。

    在BeanFactory中提供了配置框架和基本功能

    在ApplicationContext中增加了更多针对企业的功能。

  • 两者的区别

    创建对象的时间点不一样。

    ApplicationContext

    :只要一读取配置文件,默认情况下就会创建对象,类似与单例模式中的饿汉式。

    BeanFactory

    :什么时候使用,什么时候创建对象,类似与单例模式中的懒汉式。

IoC 容器实例化的方式

​ 上面已经知道 Spring 的容器是通过一个接口

org.springframework.context.ApplicationContext

表示,并负责实例化,配置和组装 Bean 对象。容器通过读取 xml 文件中的配置信息来获取关于实例化对象,配置属性等命令。

​ 而

ApplicationContext

只是一个接口,我们通常创建

ClassPathXmlApplicationContext

的实例或者

FileSystemXmlApplicationContext

的实例。

​ 前者是从类路径中获取上下文定义文件,后者是从文件系统或 URL 中获取上下文定义文件。

  • 从类路径下读取Spring配置文件,创建Spring容器
    public void userSaveTest() {
            //创建spring容器,参数指定spring配置文件的全名
            ClassPathXmlApplicationContext context = new
                    ClassPathXmlApplicationContext("applicationContext.xml");
         
         //可以使用多态方式也可以
         /*
         	 ApplicationContext context = new
                    ClassPathXmlApplicationContext("applicationContext.xml");
         */
    }
               
  • 从电脑本地读取配置文件,创建Spring容器
    public void userSaveTest() {
            //创建spring容器,参数指定spring配置文件的全名
            FileSystemXmlApplicationContext context = new
                    FileSystemXmlApplicationContext("D:\\applicationContext.xml");
    }
               

bean 标签中的属性介绍

我们知道Bean标签的作用就是在框架启动加载配置文件的时候,根据配置的类的全限定名,创建实例对象,放入Spring容器进行统一管理,

Bean标签回顾

以上我们只用到了id属性和class属性,那么来看一下是否还有其他属性。

常用属性介绍

属性 描述
id 定义配置的Bean标签的唯一标识
name 同id属性
class 表示要描述的类,也就是当加载spring配置文件的时候,要根据此属性指定的类的全限定名创建的实例对象。
factory-bean 主要用于工厂模式实例化 bean 的时候使用,这个属性用于引用配置的工厂Bean
factory-method

主要用于工厂模式实例化 bean 的时候使用,这个属性表示引用工厂Bean中的指定方法。

在普通工厂模式下factory-bean与factory-method结合使用,静态工厂时单独使用factory-method

init-method Bean初始化的时候,指定执行的方法。
destroy-method Bean销毁的时候,指定执行的方法。
scope 指定配置的Bean的作用范围,一般用多例还是单例来表述它。
lazy-init 懒加载
autowire 依赖注入
depends-on 依赖于某个实例

id和name属性

用于定义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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" name="user2" class="com.wyan.entity.User" ></bean>

</beans>


           

测试类代码

public static void main(String[] args) {
    ApplicationContext context =
        new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    System.out.println(context.getBean("user"));
    System.out.println(context.getBean("user2"));
}
           

无论是使用id还是使用name,都能从Spring容器中获取Bean

class 属性

Spring的底层是通过反射来创建的实例对象,但是他不知道创建哪个类的实例对象啊;所以通过Class属性指定要创建的实例对象的全限定类名。

factorybean 和 factorymethod 属性

这两个属性主要用于工厂模式实例化 bean 的时候使用

  1. 使用静态工厂模式获取Bean

    静态工厂类代码

    //方法和参数都是静态的
    public class User {
        
        private static User user = new User();
        
        private User() {}
    
        public static User createInstance() {
            return user;
        }
    }
               
    applicationContext配置
    <!--
    	通过factory-method属性,引用User工厂类中的createInstance方法,该方法返回值是一个user对象;
    	所以当我们使用Bean标签的id获取Bean的时候,得到的是createInstance方法的返回值  ->  user对象
    -->
    <bean id="user" class="com.wyan.entity.User" factory-method="createUserInstance"/>
               
  2. 使用普通工厂获取Bean

    普通工厂类代码

    public class BeanFactory {
    
        private static User1 user1 = new User1();
    
        private static User2 user2 = new User2();
    
        public User1 createUser1() {
            return user1;
        }
    
        public User2 createUser2() {
            return user2;
        }
    }
               
    applicationContext配置
    <!--spring实例化工厂对象 用于创建java实例 -->
    <bean id="beanFactory" class="com.wyan.factory.BeanFactory"></bean>
    
    <!-- 被工厂创建的对象实例 -->
    <bean id="user1" factory-bean="beanFactory" factory-method="createUser1"/>
               
    先要配置工厂Bean,然后引用工厂Bean的id,使用factory-method属性,引用工厂Bean中的方法,得到该方法的返回值,也就得到了User1实例对象

init-method 和 destroy-method 属性的使用

init-method 就是 bean 被初始化后执行的方法,destory-method 就是 bean 被销毁执行的代码。

  • 测试代码User类
    public class User {
    
        public User(){
            System.out.println("我被spring实例化了");
        }
    
        public void initMethod(){
            System.out.println("user类实例化时候执行的代码");
        }
        public void destoryMethod(){
            System.out.println("user类实例被销毁时候执行的代码");
        }
    }
               
  • applicationContext.xml配置
  • 测试代码
    public static void main(String[] args) {
        ApplicationContext context =
            new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    
    }
               
  • 结果
SpringIOC控制反转之XML配置

scope 属性

常用属性值

​ 默认为singleton 单例

  1. singleton:单例创建对象,当创建Spring容器的时候,对象就会创建,销毁Spring容器的时候,对象也就销毁;每次从Spring容器中获取的对象都是同一个。
  2. prototype:多例创建对象,当获取对象的时候,才会创建对象,销毁Spring容器的时候,对象不会销毁,由其它机制管理销毁;每次从Spring中获取的对象都不是同一个。
    <!--单例-->
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="singleton"/>
    <!--多例-->
    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="prototype"/>