IOC和DI的使用教程(Spring)

IoC简介

什么是Bean?
Spring Bean是被实例的,组装的及被Spring 容器管理的java对象

工厂模式发展史

在这里插紧入图片描述
在这里插入图片描述
在这里插入图片描述

IoC

IoC(Inversion Of Control)控制反转,Spring反向控制应用程序所需要使用的外部资源。
Spring控制的资源全部放置在Spring容器中,该容器称为IoC容器。
在这里插入图片描述

IOC入门案例

  1. 导入spring坐标(5.1.9.release)
  2. 编写业务层与表现层(模拟)接口与实现类
  3. 建立spring配置文件
  4. 配置所需资源(Service)为spring控制的资源
  5. 表现层(App)通过spring获取资源(Service实例)
IoC入门案例制作步骤-1(坐标依赖)

pom文件:引入Spring坐标依赖

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
    </dependencies>
IoC入门案例制作步骤-2(Service层)

定义一个业务接口方法并实现

//接口方法
public interface UserService {
//业务方法
void save();
}


//实现类
public class UserServiceImpl implements UserService{
//业务方法实现
public void save(){
System.out.println("user service running...");
}
}
IoC入门案例制作步骤-3(xml配置文件)
<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 1.创建spring控制的资源-->
    <bean id="userService" class="com.xxxx.service.impl.UserServiceImpl" />
</beans>
IoC入门案例制作步骤-4(controller层)
public static void main(String[] args) {
//2.加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//3.获取资源
UserService userService = (UserService) ctx.getBean("userService");
userService.save();
}
小节

入门案例步骤

  1. 导入Spring坐标
  2. 编写Service层
  3. xml配置文件创建Bean
  4. controller层通过读取配置文件,获取Service对象并执行方法

IoC配置(XML格式)

  • Bean标签:定义spring中的资源,受此标签定义的资源将受到spring控制
    • Bean标签id,class,name属性
    • Bean标签scope,init-method,destroy-method属性
 <bean id="beanId" 
            name="beanName1,beanName2" 
            class="ClassName"  
            scope="singleton" 
            init-method="init" destroy-method="destroy></bean>    
◆ id:bean的名称,通过id值获取bean
◆ class:bean的类型
◆ name:bean的名称,可以通过name值获取bean
◆scope:
   ◆ singleton:设定创建出的对象保存在spring容器中,是一个单例的对象
   ◆ prototype:设定创建出的对象保存在spring容器中,是一个非单例的对象
   ◆ request、session、application、 websocket :设定创建出的对象放置在web容器对应的位置
◆init-method,destroy-method  取值:bean对应的类中对应的具体方法名
   ◆ 当scope=“singleton”时,初始化spring容器时创建Bean对象
   ◆ 当scope=“prototype”时,获取对象时创建对象
时均执行一次
   ◆ 当scope=“singleton”时,关闭容器会导致bean实例的销毁,调用destroy方法一次
   ◆ 当scope=“prototype”时,对象的销毁由垃圾回收机制gc()控制,destroy方法将不会被执行
Bean标签属性小节
  • bean
  1. id
  2. class
  3. scope
  4. name
  5. init-method
  6. destroy-method
创建bean对象方式(三种)
  1. 静态工厂的形式创建bean
  2. 实例工厂的形式创建bean
  3. 构造方法的形式创建bean

静态工厂创建bean

package com.xxxx.service;
import com.xxxx.service.impl.UserServiceImpl;
//静态工厂
public class UserServiceFactory {
    public static UserService getService(){
        System.out.println("factory create object...");
        return new UserServiceImpl();
    }
}


----xml配置文件
//Bean标签创建Spring控制的资源
   <!--静态工厂创建bean-->
    <bean
     id="userService4"
     class="com.xxxx.service.UserServiceFactory" 
     factory-method="getService"/>

实例工厂创建bean

package com.xxxx.service;
import com.xxxx.service.impl.UserServiceImpl;

public class UserServiceFactory2 {

    public UserService getService(){
        System.out.println(" instance factory create object...");
        return new UserServiceImpl();
    }

}

----xml配置文件
 <!-- 先创建实例工厂的bean-->
  <bean 
    id="factoryBean" 
    class="com.xxxx.service.UserServiceFactory2"/>
     <!--实例工厂创建bean,在创建依赖工厂的对象对应的bean-->
  <bean id="userService5" 
    factory-bean="factoryBean" 																																																																																				
    factory-method="getService" />

构造方法创建bean(必须要有无参构造方法)

package com.xxxx.service.impl;

import com.xxxx.service.UserService;

public class UserServiceImpl implements UserService {

   //  无参构造方法 
    public UserServiceImpl(){
        System.out.println(" constructor is running...");
    }
    public void save() {
        System.out.println("user service running...");
    }
}


---xml配置:
bean id="userService" name="userService1,userService2" class="com.xxxx.service.impl.UserServiceImpl"/>


DI(Dependency Injection)依赖注入

  • 应用程序运行依赖的资源由Spring为其提供,资源进入应用程序的方式称为注入。

在这里插入图片描述

依赖注入的三种方式

  1. set注入(常用)
  2. 构造器(构造方法)注入
  3. 集合类型数据注入

set注入(通过set方法)

在这里插入图片描述

package com.xxxx.service.impl;

import com.xxxx.dao.BookDao;
import com.xxxx.dao.UserDao;
import com.xxxx.service.UserService;

public class UserServiceImpl implements UserService {

    private UserDao userDao;
    private BookDao bookDao;
    private int num;
    private String version;

    //1.对需要进行set注入的变量添加set方法
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
    public void setVersion(String version) {
        this.version = version;
    }
    public void setNum(int num) {
        this.num = num;
    }

//无参构造方法用于创建( UserServiceImpl)Bean
    public UserServiceImpl() {
    }

    public UserServiceImpl(UserDao userDao, int num, String version){
        this.userDao = userDao;
        this.num = num;
        this.version = version;
    }

    public void save() {
        System.out.println("user service running..."+num+" "+version);
        userDao.save();
        bookDao.save();
    }
}


---xml配置文件:
             <!--2.将要注入的资源声明为bean-->
    <bean id="userDao" class="com.xxxx.dao.impl.UserDaoImpl"> </bean>

    <!-- set注入实验 -->
    <bean id="userService" class="com.xxxx.service.impl.UserServiceImpl">
        <!--3.将要注入的引用类型的变量通过property属性进行注入,对应的name是要注入的变量名,使用ref属性声明要注入的bean的id-->
        <property name="userDao" ref="userDao"/>
        <property name="num" value="666"/>
        <property name="version" value="beijing"/>
    </bean>

set注入小结

◆ 对应的set方法
◆ bean中使用property标签注入属性
name :注入的属性名
◆ 对象类型:使用ref进行注入
◆ 其他:使用value进行注入

构造器注入(通过有参构造方法)

在这里插入图片描述

在这里插入图片描述

package com.xxxx.service.impl;

import com.xxxx.dao.BookDao;
import com.xxxx.dao.UserDao;
import com.xxxx.service.UserService;

public class UserServiceImpl implements UserService {

    private UserDao userDao;
    private BookDao bookDao;
    private int num;
    private String version;

    //1.对需要进行set注入的变量添加set方法
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
    public void setVersion(String version) {
        this.version = version;
    }
    public void setNum(int num) {
        this.num = num;
    }

//无参构造方法用于创建( UserServiceImpl)Bean
    public UserServiceImpl() {
    }

  //2.对需要进行构造注入的变量创建有参构造方法
    public UserServiceImpl(UserDao userDao, int num, String version){
        this.userDao = userDao;
        this.num = num;
        this.version = version;
    }

    public void save() {
        System.out.println("user service running..."+num+" "+version);
        userDao.save();
        bookDao.save();
    }
}

---xml配置文件

  <!--2.将要注入的资源声明为bean-->
    <bean id="userDao" class="com.xxxx.dao.impl.UserDaoImpl"> </bean>

 <!-- 构造器注入实验 -->
    <bean id="userDao" class="com.xxxx.dao.impl.UserDaoImpl">
        <constructor-arg index="2" value="123"/>
        <constructor-arg index="1" value="root"/>
        <constructor-arg index="0" value="com.mysql.jdbc.Driver"/>
    </bean>

   <!-- 构造器注入顺序实验 -->
    <bean id="userService" class="com.xxxx.service.impl.UserServiceImpl">
        <!--使用构造方法进行set注入,需要保障注入的属性与bean中定义的属性一致-->
        <!--一致指顺序一致或类型一致或使用index解决该问题-->
        <constructor-arg name="userDao" ref="userDao"/>
        <constructor-arg name="num" value="666666"/>
        <constructor-arg name="version" value="itcast"/>
    </bean>

构造方法注入小节

有参构造方法
◆ bean中使用 constructor-arg标签注入属性
◆ name表示注入的属性名
◆ 对象:使用ref进行注入
◆ 其他:使用value进行注入
◆ 支持按类型注入
◆ 支持按顺序注入

集合类型数据注入(通过构造方法)

数据类型:array,list,set,map,props

在这里插入图片描述

package com.xxxx.dao.impl;

import com.xxxx.dao.BookDao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties;

public class BookDaoImpl implements BookDao {

    private ArrayList al;
    private Properties properties;
    private int[] arr;
    private HashSet hs;
    private HashMap hm ;

    public void setAl(ArrayList al) {
        this.al = al;
    }

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

    public void setArr(int[] arr) {
        this.arr = arr;
    }

    public void setHs(HashSet hs) {
        this.hs = hs;
    }

    public void setHm(HashMap hm) {
        this.hm = hm;
    }


    public void save() {
        System.out.println("book dao running...");
        System.out.println("ArrayList:"+al);
        System.out.println("Properties:"+properties);
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        System.out.println("HashSet:"+hs);
        System.out.println("HashMap:"+hm);
    }
}

xml配置文件
 <!-- 集合注入顺序实验 -->
  
  <bean id="bookDao" class="com.xxxx.dao.impl.BookDaoImpl">
        <property name="al">
            <list>
                <value>beijing</value>
                <value>66666</value>
            </list>
        </property>
        <property name="properties">
            <props>
                <prop key="name">123666</prop>
                <prop key="value">666666</prop>
            </props>
        </property>
        <property name="arr">
            <array>
                <value>123456</value>
                <value>66666</value>
            </array>
        </property>
        <property name="hs">
            <set>
                <value>qqqqq</value>
                <value>66666</value>
            </set>
        </property>
        <property name="hm">
            <map>
                <entry key="name" value="itheima66666"/>
                <entry key="value" value="6666666666"/>
            </map>
        </property>
    </bean>

使用p命名空间简化配置

在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值