• 深入谈谈 Java IOC 和 DI


    1.前言

      不得不说, IOC和DI 在写代码时经常用到。还有个就是在面试时 ,面试官老喜欢问 IOC 和DI是什么的问题,都快被问吐了,

    可是,仍然会让许多人说的支支吾吾。

      为什么?

    第一,因为这个知识实在是太基础了,忽略了操作的叫法,即便开发时老是在使用这个知识点,但是并不知道一直写的这个原来是叫这个啊!
    第二,不知道底层原理,谁不知道IOC是控制反转 ,DI是依赖注入?那么面试官来了句为什么?怎么用?那岂不是就凉凉了?        

    2.定义:

    IOC ,英文全称是Inverse of Control,控制反转。
    DI,英文全称是Dependency Injection ,依赖注入。

    3.总结

    (1)IOC控制反转 ,就是将依赖类的控制权从容器类中移除,将其移到容器类外部去,使用容器类之前,需要从外部将依赖类注入进来。
    (2)那么注入依赖类的过程就是DI,意为依赖注入。
    (3)能够将依赖类注入容器类的方式共有4种,但是DI依赖注入只占其中的3种,
      分别是构造函数注入【也称构造器注入】、setter注入【也称属性注入】、接口注入【具有侵入性,不建议使用】。
      还有一种是使用javabean容器注入。
    (4)而初始化Javabean的容器方式有两种,分别是
      低级容器 XMLBeanFactory【实例对象类型是BeanFactory】、   高级容器 ClassPathXmlApplicationContext【实例对象类型是ApplicationContext】   分别将依赖类和容器类使用XML文件注册javabean,然后在容器类的
    <bean>标签内配置注入依赖类的信息,
      可以直接使用属性 p:   格式是p:【属性名】-ref
    =“【依赖类的<bean>标签id】”   也可以使用<bean>里面使用<property>标签配置

     4.不使用IOC

    这里演示不使用IOC的写法

    目录结构

     依赖类

    package com.example.javabaisc.ioc;
    
    /**
     * 依赖类
     */
    public class MDependency {
        public String food(){
            return "苹果";
        }
    }
    View Code

    容器类

    package com.example.javabaisc.ioc;
    
    /**
     * 容器类
     */
    public class MContainer {
        public void eat(){
            System.out.println("饿了,有什么吃的?");
            //实例依赖类
            MDependency m = new MDependency();
            System.out.println(m.food());
        }
    }
    View Code

    测试类

    package com.example.javabaisc.ioc;
    
    import org.junit.Test;
    
    public class IOCTest {
    
        @Test
        public void t(){
            //实例容器类
            MContainer mContainer = new MContainer();
            mContainer.eat();
        }
    }
    View Code

    打印结果

     5.构造函数注入

    目录结构

     依赖类

    package com.example.javabaisc.ioc;
    
    /**
     * 依赖类
     */
    public class MDependency {
        public String food(){
            return "苹果";
        }
    }
    View Code

    容器类

    package com.example.javabaisc.ioc;
    
    /**
     * 容器类
     */
    public class MContainer {
        //存储 依赖类对象
        private final MDependency m;
    
        //有参构造器
        public MContainer(MDependency mDependency){
            this.m = mDependency;
        }
    
        public void eat(){
            System.out.println("饿了,有什么吃的?");
            System.out.println(m.food());
        }
    }
    View Code

    测试类

    package com.example.javabaisc.ioc;
    
    import org.junit.Test;
    
    public class IOCTest {
    
        @Test
        public void t(){
            //实例依赖类
            MDependency mDependency = new MDependency();
            //实例容器类,并将依赖类对象作为参数注入
            MContainer mContainer = new MContainer(mDependency);
            mContainer.eat();
        }
    }
    View Code

    打印结果

     

     6.setter注入

    目录结构

     依赖类

    View Code

    容器类

    package com.example.javabaisc.ioc;
    
    /**
     * 容器类
     */
    public class MContainer {
        //存储 依赖类对象
        private  MDependency m;
    
        //setter方法
        public void setM(MDependency m) {
            this.m = m;
        }
    
        public void eat(){
            System.out.println("饿了,有什么吃的?");
            System.out.println(m.food());
        }
    }
    View Code

     测试类

    package com.example.javabaisc.ioc;
    
    import org.junit.Test;
    
    public class IOCTest {
    
        @Test
        public void t(){
            //实例依赖类
            MDependency mDependency = new MDependency();
            //实例容器类
            MContainer mContainer = new MContainer();
            //调用set方法将依赖类对象作为参数注入
            mContainer.setM(mDependency);
            //
            mContainer.eat();
        }
    }
    View Code

    打印结果

      7.接口注入

     接口

    package com.example.javabaisc.ioc;
    
    public interface MDependencyInterface {
        //注入依赖类对象
        void food(MDependency mDependency);
    }
    View Code

     依赖类

    package com.example.javabaisc.ioc;
    
    /**
     * 依赖类
     */
    public class MDependency {
        public String food(){
            return "苹果";
        }
    }
    View Code

    容器类

    package com.example.javabaisc.ioc;
    
    /**
     * 容器类
     */
    public class MContainer implements MDependencyInterface {
        //存储 依赖类对象
        private MDependency m;
    
        //重写接口方法【实现接口】
        @Override
        public void food(MDependency foodname) {
            m = foodname;
        }
    
        public void eat() {
            System.out.println("饿了,有什么吃的?");
            System.out.println(m.food());
        }
    
    
    }
    View Code

     测试类

    package com.example.javabaisc.ioc;
    
    import org.junit.Test;
    
    public class IOCTest {
    
        @Test
        public void t(){
            //实例依赖类
            MDependency mDependency = new MDependency();
            //实例容器类
            MContainer mContainer = new MContainer();
            //调用接口方法将依赖类对象作为参数注入
            mContainer.food(mDependency);
            //
            mContainer.eat();
        }
    }
    View Code

    打印结果

    8.javabean容器注入

    目录结构

     javabean配置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:p="http://www.springframework.org/schema/p"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="mDependency" class="com.example.javabaisc.ioc.MDependency"/>
        <!--写法一 -->
        <bean id="mContainer" class="com.example.javabaisc.ioc.MContainer" p:m-ref="mDependency"/>
        <!--写法二 -->
        <!--    <bean id="mContainer" class="com.example.javabaisc.ioc.MContainer">-->
        <!--        <property name="m" ref="mDependency"/>-->
        <!--    </bean>-->
    
    </beans>
    View Code

    依赖类

    package com.example.javabaisc.ioc;
    
    /**
     * 依赖类
     */
    public class MDependency {
        public String food(){
            return "苹果";
        }
    }
    View Code

    容器类

    package com.example.javabaisc.ioc;
    
    /**
     * 容器类
     */
    public class MContainer {
        //存储 依赖类对象
        private MDependency m;
    
        public void eat() {
            System.out.println("饿了,有什么吃的?");
            System.out.println(m.food());
        }
    
        //这是xml文件的javabean使用setter方式将依赖类对象注入进来
        public void setM(MDependency m) {
            this.m = m;
        }
    
    }
    View Code

    测试类

    package com.example.javabaisc.ioc;
    
    import org.junit.Test;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.core.io.ClassPathResource;
    
    public class IOCTest {
        @Test
        public void t() {
            //低级容器【被抛弃了,不建议使用】
            //初始化xml文件里的javabean
    //        BeanFactory javabean = new XmlBeanFactory(new ClassPathResource("iocConfig.xml"));
            //高级容器
            //全局初始化xml文件里的javabean
            ApplicationContext javabean = new ClassPathXmlApplicationContext("iocConfig.xml");
            //实例容器类
            MContainer mContainer = (MContainer) javabean.getBean("mContainer");
            mContainer.eat();
    
        }
    }
    View Code

    打印结果

  • 相关阅读:
    关于接口与抽象类
    C# 高级编程(笔记4)
    泛型与委托
    C# 高级编程(笔记2)
    构造函数的代码膨胀问题
    C# 高级编程(笔记3)
    C# 高级编程(笔记1)
    Web(7)补充
    理解synchronized对象锁
    robbin谈管理:改造团队的经验
  • 原文地址:https://www.cnblogs.com/c2g5201314/p/13138908.html
Copyright © 2020-2023  润新知