栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SSM框架学习——Spring的IoC与DI(容器、bean、依赖注入)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SSM框架学习——Spring的IoC与DI(容器、bean、依赖注入)

1. 核心概念
  • IoC(Inversion of Control)控制反转
    • 使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转
  • Spring技术对IoC思想进行了实现
    • Spring提供了一个容器,称为IoC容器,用来充当IoC思想中的“外部
    • IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
  • DI(Dependency Injection)依赖注入
    • 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
  • 目标:充分解耦
2. IoC入门案例

1. 导入Spring坐标



    4.0.0

    org.example
    spring_01_quickstart
    1.0-SNAPSHOT


    
        17
        17
    

    
        
            org.springframework
            spring-context
            5.2.10.RELEASE
        
        
            junit
            junit
            4.12
            test
        
    

2. 定义Spring管理的类(接口)

public interface BookDao {
    public void save();
}
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
}
public interface BookService {
    public void save();
}
public class BookServiceImpl implements BookService {
    private BookDao bookDao = new BookDaoImpl();
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

3. 创建Spring配置文件,配置对应类作为Spring管理的bean




    
    
    

注意:bean定义时id属性在同一个上下文中不能重复

4. 初始化IoC容器(Spring核心容器/Spring容器),通过容器获取bean

package com.lenyoo;

import com.lenyoo.dao.BookDao;
import com.lenyoo.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
        // 3. 获取IOC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 4. 获取bean
//        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
//        bookDao.save();
        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }
}
3. DI入门案例

1. 删除使用new的形式创建对象的代码

public class BookServiceImpl implements BookService {
    // 5. 删除业务层中使用new的方式创建的dao对象
    private BookDao bookDao ;
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }

2. 提供依赖对象对应的setter方法

public class BookServiceImpl implements BookService {
    // 5. 删除业务层中使用new的方式创建的dao对象
    private BookDao bookDao;
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }

    // 6. 提供对应的set方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}

3. 配置service与dao之间的关系




    
    

    
        
        
    


注意:配置中的两个bookDao的含义是不一样的

3. IoC相关内容 3.1 bean的基础配置 3.1.1 bean的name属性

3.1.2 bean的作用范围scope配置


3.2 bean实例化

对象已经能交给Spring的IOC容器来创建了,但是容器是如何来创建对象的呢?就需要研究下bean的实例化过程。

3.2.1 实例化bean的三种方式——构造方法(常用)
  • 提供可访问的构造方法
public class BookDaoImpl implements BookDao {

    public BookDaoImpl() {
        System.out.println("book dao constructor is running ...");
    }

    public void save() {
        System.out.println("book dao save ...");
    }
}
  • 配置
	
    
  • 无参构造方法如果不存在,将抛出异常BeanCreationException
3.2.2 实例化bean的三种方式——静态工厂(了解)
  • 静态工厂
public class OrderDaoFactory {
    public static OrderDao getOrderDao(){
        System.out.println("factory setup...");
        return new OrderDaoImpl();
    }
}
  • 配置
    
    
3.2.3 实例化bean的三种方式——实例工厂(了解)
  • 实例工厂
public class UserDaoFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}
  • 配置
    
    

    

3.2.4 实例化bean的第四种方式——FactoryBean(实用)
  • FactoryBean
public class UserDaoFactoryBean implements FactoryBean {
    // 代替原始实例工厂中创建对象的方法
    @Override
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }

    @Override
    public Class getObjectType() {
        return UserDao.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}
  • 配置
    
    
3.3 bean的生命周期

(1)关于Spring中对bean生命周期控制提供了两种方式:

  • 在配置文件中的bean标签中添加init-method和destroy-method属性

  • 类实现InitializingBean与DisposableBean接口,这种方式了解下即可。
package com.lenyoo.service.impl;

import com.lenyoo.dao.BookDao;
import com.lenyoo.service.BookService;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
    private BookDao bookDao;

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }


    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("service destroy");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("service init");
    }
}

(2)对于bean的生命周期控制在bean的整个生命周期中所处的位置如下:

  • 初始化容器
    • 1.创建对象(内存分配)
    • 2.执行构造方法
    • 3.执行属性注入(set操作)
    • 4.执行bean初始化方法
  • 使用bean
    • 1.执行业务操作
  • 关闭/销毁容器
    • 1.执行bean销毁方法

(3)关闭容器的两种方式:

  • ConfigurableApplicationContext是ApplicationContext的子类
    • close()方法
    • registerShutdownHook()方法
import com.lenyoo.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppForLifeCycle {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();
//        ctx.registerShutdownHook();
        ctx.close();
    }
}
4. DI相关内容

依赖注入方式,分别是:

  • setter注入
    • 简单类型
    • 引用类型
  • 构造器注入
    • 简单类型
    • 引用类型
4.1 Setter注入 4.1.1 Setter注入——引用类型
  • 在bean中定义引用类型属性,并提供可访问的set方法
public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }


    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
        userDao.save();
    }
    
}
  • 配置中使用property标签ref属性注入引用类型对象
    
    

    
        
        
    
4.1.2 Setter注入——简单类型
  • 在bean中定义简单类型属性并提供可访问的set方法
public class BookDaoImpl implements BookDao {

    private int connectionNum;
    private String databaseName;

    public void setConnectionNum(int connectionNum) {
        this.connectionNum = connectionNum;
    }

    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }

    public void save() {
        System.out.println("book dao save ..." + databaseName + "," + connectionNum);
    }

}
  • 配置中使用property标签value属性注入简单类型数据
    
        
        
    
4.2 构造器注入(了解) 4.2.1 构造器注入——引用类型(了解)
  • 在bean中定义引用类型属性并提供可访问的构造方法
public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    private UserDao userDao;

    public BookServiceImpl(BookDao bookDao, UserDao userDao) {
        this.bookDao = bookDao;
        this.userDao = userDao;
    }
  • 配置中使用constructor-arg标签ref属性注入引用类型对象



	
    

4.2.2 构造器注入——简单类型(了解)
  • 在bean中定义简单类型属性并提供可访问的构造方法
public class BookDaoImpl implements BookDao {

    private String databaseName;
    private int connectionNum;

    public BookDaoImpl(String databaseName, int connectionNum) {
        this.databaseName = databaseName;
        this.connectionNum = connectionNum;
    }

    public void save() {
        System.out.println("book dao save ..." + databaseName + "," + connectionNum);
    }

}
  • 配置中使用constructor-arg标签value属性注入简单类型数据

	
	

4.3 依赖自动装配
  • IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
  • 自动装配方式
    • 按类型(常用)
    • 按名称
    • 按构造方法
    • 不启用自动装配
  • 配置中使用bean标签autowire属性设置自动装配的类型



注意

  1. 自动装配用于引用类型依赖注入,不能对简单类型进行操作
  2. 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
  3. 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
  4. 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
4.4 集合注入
public class BookDaoImpl implements BookDao {

    private int[] array;
    private List list;
    private Set set;
    private Map map;
    private Properties properties;

    public void setArray(int[] array) {
        this.array = array;
    }

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

    public void setSet(Set set) {
        this.set = set;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public void save() {
        System.out.println("book dao save ...");
        System.out.println("遍历数组:" + Arrays.toString(array));
        System.out.println("遍历list:" + list);
        System.out.println("遍历Set:" + set);
        System.out.println("遍历Map:" + map);
        System.out.println("遍历Properties:" + properties);
    }

}

	
        
            
                100
                200
                300
            
        
        
            
                itcast
                itheima
                boxuegu
            
        
        
            
                itcast
                itheima
                boxuegu
                chuanzhihui
            
        
        
            
                
                
                
            
        
        
            
                china
                zhejiang
                hangzhou
            
        
    
5. IOC/DI配置管理第三方bean 5.1 案例:数据源对象管理

该案例使用数据源Druid(德鲁伊)和C3P0来配置学习
步骤1:导入第三方数据源依赖

        
            com.alibaba
            druid
            1.1.16
        
        
            c3p0
            c3p0
            0.9.1.2
        
        
            mysql
            mysql-connector-java
            5.1.16
        

步骤2:配置第三方bean

	
        
        
        
        
    

    
        
        
        
        
        
    

步骤3:从IOC容器中获取对应的bean对象

public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        DataSource dataSource = (DataSource) ctx.getBean("dataSource");
        System.out.println(dataSource);
    }
}
5.2 加载properties文件
  • 开启context命名空间




  • 使用context空间,加载指定properties文件


  • 使用属性占位符${}读取properties文件中的属性


	
	
	
	



	

当有多个properties配置文件需要被加载,该如何配置?

  • 不加载系统属性

  • 加载多个properties文件

  • 加载所有properties文件

  • 加载properties文件标准格式

  • 从类路径或jar包中搜索并加载properties文件

6. 核心容器 6.1 容器的创建方式
  • 方式一:类路径加载配置文件
// 1. 加载类路径下的配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  • 方式二:文件路径加载配置文件
// 2. 从文件系统下加载配置文件
ApplicationContext ctx = new FileSystemXmlApplicationContext("//Users/lenyoo/Documents/code/spring-app/spring_10_container/src/main/resources/applicationContext.xml");
6.2 bean的三种获取方式
  • 方式一:使用bean名称获取
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
  • 方式二:使用bean名称获取并指定类型
BookDao bookDao = ctx.getBean("bookDao", BookDao.class);
  • 方式三:使用bena类获取
BookDao bookDao = ctx.getBean(BookDao.class);
6.3 BeanFactory
  • 使用BeanFactory创建的容器是延迟加载
  • 使用ApplicationContext创建的容器是立即加载
  • 具体BeanFactory如何创建只需要了解即可。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/886016.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号