zoukankan      html  css  js  c++  java
  • Spring IOC(控制反转)详解及示例

      控制反转——Spring通过一种称作控制反转(IOC)的技术促进了低耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。

      下面简单通过实例来看一下控制反转的好处:

      首先先定义一个Cat.java类

    package com.model;
    
    public class Cat  {
        private String name="kitty";
        private int age=2;
        
        public void sleep(){
            System.out.println(name+"猫睡了");
        }
    }

    再定义一个main函数的类调用Cat

    public class Test {
    
        public static void main(String[] args) {
            Cat p = new Cat();
            p.sleep();
            }

      这样会输出 kitty猫睡了 这句话。

      

      首先我们来分析一下代码:在main中new 一个Cat,其实这样Cat的名字和年龄就已经固定了

      重点来了:如果我要换个猫呢?那么new的对象就要从Cat里面修改。这岂不是非常麻烦的事而且破环了项目的一体性。实际上现在工作的控制权并不在main中而是在JavaWork中,而正确的解决方法是将控制权交到mian中!

      要想实现控制反转:

      首先定义一个接口,让所有的宠物都通过这个接口

    package com.model;
    
    public interface IPet {
        public String getName();
        public void setName(String name);
        public void sleep();
    }

      再将Cat类添加实现方法

    package com.model;
    
    public class Cat implements IPet {
        private String name;
        private int age;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public void sleep(){
            System.out.println(name+"猫睡了");
        }
    }

      再造一个Dog类实现IPet接口

    package com.model;
    
    public class Dog implements IPet {
        private String name;
        private int age;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        
        public Dog(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public void sleep(){
            System.out.println(name+"狗睡了");
        }
    }

      再做一个Human类添加另外一个方法,其中包含了IPet这个接口实现的Cat和Dog类的feed方法

    package com.model;
    
    public class Human  {
        private IPet pet;
        public IPet getPet() {
            return pet;
        }
        public void setPet(IPet pet) {
            this.pet = pet;
        }
        public void feed(){
            System.out.println("正在喂养"+pet.getName());
            pet.sleep();
        }
    }

      在这里,我们采用Spring的xml配置来实现控制反转(beans.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
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <bean id="pet1" class="com.model.Dog">
           <constructor-arg name="name" value="wang"></constructor-arg>
           <constructor-arg name="age" value="2"></constructor-arg>
        </bean>
        
        <bean id="pet2" class="com.model.Cat">
           <property name="name" value="miao"></property>
           <property name="age" value="3"></property>
        </bean>
        
        <bean id="pet3" class="com.model.Mouse" init-method="born">
           
        </bean>
        <bean id="human" class="com.model.Human" >
           <property name="pet" ref="pet1"></property>
        </bean>
        
    
    </beans>

      最后做一个带有main函数的测试类

    package com.model;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Test {
    
        public static void main(String[] args) {
    //        IPet p = new Dog();
    //        p.sleep();
            ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            IPet p1=(IPet)context.getBean("pet1");
            IPet p2=(IPet)context.getBean("pet2");
            IPet p3=(IPet)context.getBean("pet3");
            p1.sleep();
            p2.sleep();
            p3.sleep();
            
            Human h = (Human)context.getBean("human");
            h.feed();
        }
    
    }

      此时的输出结果为

    wang狗睡了
    miao猫睡了
    laoshu鼠睡了
    正在喂养wang
    wang狗睡了

      因为在beans.xml中定义的pet1狗叫wang年龄2,pet2猫叫miao年龄3,human只喂养了pet1狗,再调用pet1的sleep,然后可以发现,我定义了一个pet3的老鼠,但是我并没有给它名字和年龄,依然能出来结果,是因为调用了init-method="born"方法,这个写法的意思是调用此类内部的方法born,看一下Mouse.java类的写法:

    package com.model;
    
    public class Mouse implements IPet{
        private String name;
        private int age;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public void born(){
            name="laoshu";
            age=1;
        }
        public void sleep(){
            System.out.println(name+"鼠睡了");
        }
    }

      是不是一目了然。所以如果要换个宠物来养,那么直接修改beans.xml里面human的ref里面的定义的bean的id就好了。

  • 相关阅读:
    03 Python之变量以及常量介绍
    看女程序员是如何处理男友出轨,网友回复更精彩
    四面美团,收割 offer
    MySQL 优化实战记录
    龙岗一个月350的出租房,我搬出来了
    程序员工作 996 生病 ICU ?
    真的有人在偷听我们讲话么?
    一次非常有趣的 SQL 优化经历
    如何阅读Java源码?
    从 0 开始手写一个 Mybatis 框架,三步搞定!
  • 原文地址:https://www.cnblogs.com/claricre/p/6636678.html
Copyright © 2011-2022 走看看