Ioc/DI思想

目标:充分解耦
使用IoC容器管理bean(IoC) ServiceDao
在IoC容器内将有依赖关系的bean进行关系绑定(DI)

最终效果
使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系

Ioc/DI入门案例

1.引入springframework依赖

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>

2.创建Spring配置文件
命名为 applicationContext.xml

在配置文件中配置Bean

property name="bookDao" ref="bookDao"中
name代表的是需要放置Bean的位置
ref代表的是去哪里得到这个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-->
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <property name="bookDao" ref="bookDao"/>
    </bean>
</beans>

new一个IoC容器开始使用

public class App2 {
    public static void main(String[] args) {
        //获取Ioc容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //获取bean
        BookService bookService = (BookService) context.getBean("bookService");
        bookService.bookSave();
    }
}

bean配置别名

用name定义, 使用(,)(;)( )分隔

    <bean id="bookDao" name="dao booqidao" class="com.itheima.dao.impl.BookDaoImpl"></bean>

    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" scope="prototype">
        <property name="bookDao" ref="booqidao"/>
    </bean>

bean单例多例切换

创建bean的时候默认是单例的 但是可以通过scope更换

    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" scope="prototype">
        <property name="bookDao" ref="booqidao"/>
    </bean>

适合交给容器进行管理的bean

由于创建bean时默认是单例的, 所以有些类不适合交给容器管理

适合的bean:

  1. 表现层对象
  2. 业务层对象
  3. 数据层对象
  4. 工具对象

不适合:

  1. 封装实体的域对象

实例化bean的三种方式

1. 通过bean的构造函数实例化bean

  1. 静态工厂

    <bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"></bean>

    这样配置也可以把bean实例化

  2. 实体工厂实例化bean

    <!--    实例化工厂bean-->
    <bean id="userDaoFactory" class="com.itheima.factory.UserDaoFactory"></bean>
    
    <bean id="userDao" factory-bean="userDaoFactory" factory-method="getUserDao"></bean>

    要先把工厂类存到容器中 再指定factory-bean和factory-method

  • 由第三种方式改良的FactoryBean
    创建一个FactoryBean并implements FactoryBean<>
  • package com.itheima.factory;
    
    import com.itheima.dao.UserDao;
    import com.itheima.dao.impl.UserDaoImpl;
    import org.springframework.beans.factory.FactoryBean;
    
    public class UserDaoFactoryBean implements FactoryBean<UserDao> {
        //代替实例工厂中创建对象的方法
        @Override
        public UserDao getObject() throws Exception {
            return new UserDaoImpl();
        }
    
        @Override
        public Class<?> getObjectType() {
            return UserDao.class;
        }
    
        @Override
        public boolean isSingleton() {
            return true;//这个factoryBean造出来的对象是单例的
        }
    }
    

    在Spring配置文件中配置Bean

    <bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>

    Bean的生命周期

    1. 定义初始化和销毁方法

    public class UserDaoImpl implements UserDao {
        @Override
        public void save() {
            System.out.println("UserDao is running....");
        }
        public void init(){
            System.out.println("init...");
        }
        public void destory(){
            System.out.println("destory...");
        }
    }
    

    2. 在Spring配置文件中指定初始化和销毁方法

    <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" init-method="init" destroy-method="destory"/>

    3. 注册钩子

    public class Life {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserDao userDao = (UserDao) context.getBean("userDao");
            context.registerShutdownHook();//否则容器不会正常关闭
            userDao.save();
        }
    }