控制反转(IOC) & 依赖注入(DI)

6 篇文章 0 订阅

@[TOC](控制反转(IOC) & 依赖注入(DI))

什么是控制反转(IOC) & 依赖注入(DI)

控制反转(IOC)
依赖注入(DI)

项目后端代码结构
在这里插入图片描述

引入IOC之前的代码编写

User模块实体类:User.java

package entity;

public class User {
    private Integer id;
    private String name;
    private Integer gender;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }
}

User模块视图类:UserVo.java

package vo;

import entity.User;

public class UserVo {
    private Integer id;
    private String name;
    private Integer gender;
    private String genderName;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Integer getGender() {
        return gender;
    }

    public void setGender(Integer gender) {
        this.gender = gender;
    }

    public String getGenderName() {
        return genderName;
    }

    public void setGenderName(String genderName) {
        this.genderName = genderName;
    }

    public UserVo() {
    }

    public UserVo(User user) {
        this.id = user.getId();
        this.name = user.getName();
        this.gender = user.getGender();
    }

    @Override
    public String toString() {
        return "UserVo{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender=" + gender +
                ", genderName='" + genderName + '\'' +
                '}';
    }
}

User模块Dao层:UserDao.java

package dao;

import entity.User;

public interface UserDao {
    User getEntity(Integer id);
}

User模块Dao层实现类:UserDaoImpl.java

package dao.impl;

import dao.UserDao;
import entity.User;

public class UserDaoImpl implements UserDao {
    public User getEntity(Integer id) {
        User user = new User();
        user.setId(1);
        user.setName("Anne");
        user.setGender(0);
        return user;
    }
}

User模块Service层:UserService.java

package services;

import vo.UserVo;

public interface UserService {
    UserVo getVo(Integer id);
}

User模块Service层实现类:UserServiceImpl.java

package services.impl;

import dao.UserDao;
import dao.impl.UserDaoImpl;
import entity.User;
import services.UserService;
import vo.UserVo;

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public UserVo getVo(Integer id) {
        userDao = new UserDaoImpl();
        User user = userDao.getEntity(id);
        UserVo userVo = new UserVo(user);
        userVo.setGenderName(userVo.getGender() == 0 ? "female" : "male");
        return userVo;
    }
}

User模块Controller层:UserController.java

package controller;

import services.UserService;
import services.impl.UserServiceImpl;
import vo.UserVo;

public class UserController {
    private UserService userService;

    public UserVo getVo(Integer id) {
        // 手动实例化Service
        userService = new UserServiceImpl();
        // 执行Service层方法并返回
        return userService.getVo(id);
    }
}

User模块测试类:UserTest.java

import controller.UserController;
import vo.UserVo;

public class UserTest {
    public static void main(String[] args) {
        // 手动实例化Controller
        UserController userController = new UserController();
        // 执行Controller层方法
        UserVo userVo = userController.getVo(1);
        System.out.println(userVo);
    }
}

运行测试结果如下:

在这里插入图片描述

引入IOC(基于Xml文件)后的代码修改

使用SpringIOC之前首先需要导入Spring框架基础包并且添加Spring核心配置文件

将依赖交给Spring的beanFactory管理:

applicationContext.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"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        https://www.springframework.org/schema/util/spring-util.xsd
       ">

    <!-- bean definitions here -->

    <bean id="userDao" class="dao.impl.UserDaoImpl"/>
    <bean id="userService" class="services.impl.UserServiceImpl"/>
    <bean id="userController" class="controller.UserController"/>

</beans>

User模块测试类:UserTest.java

import controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import vo.UserVo;

public class UserTest {
//    public static void main(String[] args) {
//        // 手动实例化Controller
//        UserController userController = new UserController();
//        // 执行Controller层方法
//        UserVo userVo = userController.getVo(1);
//        System.out.println(userVo);
//    }

    public static void main(String[] args) {
        // 读取配置文件刷新Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        // 从Spring容器拿Controller
        UserController userController = (UserController) context.getBean("userController");
        // 执行Controller层方法,因为之后还需要用到context对象,故下传
        //把ApplicationContext传到Controller层继续使用
        UserVo userVo = userController.getVo(1, context);
        System.out.println(userVo);
    }
}


User模块Controller层:UserController.java

package controller;

import org.springframework.context.ApplicationContext;
import services.UserService;
import vo.UserVo;

public class UserController {
    private UserService userService;

//    public UserVo getVo(Integer id) {
//        // 手动实例化Service
//        userService = new UserServiceImpl();
//        // 执行Service层方法并返回
//        return userService.getVo(id);
//    }

    public UserVo getVo(Integer id, ApplicationContext context) {
        // 从Spring容器拿Service
        userService = (UserService) context.getBean("userService");
        // 执行Service层方法,因为之后还需要用到context对象,故下传
        return userService.getVo(id, context);
    }
}

User模块Service层实现类:UserServiceImpl.java

package services.impl;

import dao.UserDao;
import entity.User;
import org.springframework.context.ApplicationContext;
import services.UserService;
import vo.UserVo;

public class UserServiceImpl implements UserService {
    private UserDao userDao;

//    public UserVo getVo(Integer id) {
//        // 手动实例化Dao
//        userDao = new UserDaoImpl();
//        // 执行Dao层方法
//        User user = userDao.getEntity(id);
//        // 省略业务逻辑处理。。。
//        UserVo userVo = new UserVo(user);
//        userVo.setGenderName(userVo.getGender() == 0 ? "female" : "male");
//        return userVo;
//    }

    public UserVo getVo(Integer id, ApplicationContext context) {
        // 从Spring容器拿Dao
        userDao = (UserDao) context.getBean("userDao");
        // 执行Dao层方法
        User user = userDao.getEntity(id);
        // 省略业务逻辑处理。。。
        UserVo userVo = new UserVo(user);
        userVo.setGenderName(userVo.getGender() == 0 ? "female" : "male");
        return userVo;
    }
}

测试结果如下图所示

在这里插入图片描述

IOC(基于注解)的代码修改

常用注解

@Component:一般用于通用组件类上使用的注解
@Service:一般用于业务逻辑层上使用的注解
@Controller:一般用于流程控制层上使用的注解
@Repository:一般用于数据持久层上使用的注解

核心配置文件修改:applicationContext.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"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util
        https://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- bean definitions here -->

<!--    <bean id="userDao" class="dao.impl.UserDaoImpl"/>-->
<!--    <bean id="userService" class="services.impl.UserServiceImpl"/>-->
<!--    <bean id="userController" class="controller.UserController"/>-->

    <!-- bean definitions here -->

    <context:component-scan base-package="dao"/>
    <context:component-scan base-package="services"/>
    <context:component-scan base-package="controller"/>

</beans>

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

测试结果如下图所示

在这里插入图片描述

引入DI

常用注解

@Autowired注解自动按照类型注入会从容器中寻找符合依赖类型的实例,但是也有缺点:因为时按照类型匹配,如果找不到匹配的实例也会抛出异常,如果容器中有多个匹配的类型也会抛出异常,需要指定引入的实例id
@Qualifier注解作用是在按照类型注入的基础之上,再按照Bean的id注入。所以如果是使用了@Autowire注解自动注入,但是容器中却有多个匹配的实例,可以搭配此注解,指定需要注入的实例id
@Resource注解作用是指定依赖按照id注入,还是按照类型注入。当只使用注解但是不指定注入方式的时候,默认按照id注入,找不到再按照类型注入。

User模块Controller层:UserController.java

package controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import services.UserService;
import vo.UserVo;

@Controller
public class UserController {
    //改为自动注入
    @Autowired
    private UserService userService;

//    public UserVo getVo(Integer id) {
//        // 手动实例化Service
//        userService = new UserServiceImpl();
//        // 执行Service层方法并返回
//        return userService.getVo(id);
//    }

//    public UserVo getVo(Integer id, ApplicationContext context) {
//        // 从Spring容器拿Service
//        userService = (UserService) context.getBean("userService");
//        // 执行Service层方法,因为之后还需要用到context对象,故下传
//        return userService.getVo(id, context);
//    }
    public UserVo getVo(Integer id, ApplicationContext context){
        return userService.getVo(id, context);
    }
}

User模块Dao层实现类:UserDaoImpl.java

package dao.impl;

import dao.UserDao;
import entity.User;
import org.springframework.stereotype.Repository;

@Repository
public class UserDaoImpl implements UserDao {
    public User getEntity(Integer id) {
        User user = new User();
        user.setId(1);
        user.setName("Anne");
        user.setGender(0);
        return user;
    }
}

User模块Service层实现类:UserServiceImpl.java

package services.impl;

import dao.UserDao;
import entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import services.UserService;
import vo.UserVo;

@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired
    @Qualifier("userDaoImpl")
    private UserDao userDao;

//    public UserVo getVo(Integer id) {
//        // 手动实例化Dao
//        userDao = new UserDaoImpl();
//        // 执行Dao层方法
//        User user = userDao.getEntity(id);
//        // 省略业务逻辑处理。。。
//        UserVo userVo = new UserVo(user);
//        userVo.setGenderName(userVo.getGender() == 0 ? "female" : "male");
//        return userVo;
//    }

//    public UserVo getVo(Integer id, ApplicationContext context) {
//        // 从Spring容器拿Dao
//        userDao = (UserDao) context.getBean("userDao");
//        // 执行Dao层方法
//        User user = userDao.getEntity(id);
//        // 省略业务逻辑处理。。。
//        UserVo userVo = new UserVo(user);
//        userVo.setGenderName(userVo.getGender() == 0 ? "female" : "male");
//        return userVo;
//    }

    public UserVo getVo(Integer id, ApplicationContext context) {
        // 执行Dao层方法
        User user = userDao.getEntity(id);
        // 省略业务逻辑处理。。。
        UserVo userVo = new UserVo(user);
        userVo.setGenderName(userVo.getGender() == 0 ? "female" : "male");
        return userVo;
    }
}

测试结果如下

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值