PI-KA-CHU / PIKACHU-JAVA-Notebook

用于记录学习笔记
8 stars 4 forks source link

Spring IOC(控制反转) #67

Open PI-KA-CHU opened 5 years ago

PI-KA-CHU commented 5 years ago

Spring IOC(控制反转)



一、什么是IOC



二、为什么要用IOC?


a. 原始的对象间的关系

image


b.基于IOC容器的对象间的关系

image


从上面的图中对比可以看出,原始的对象间的关系存在着耦合过高的问题,在大型软件系统中其耦合程度更是极其复杂,IOC容器将复杂的系统分解成相互合作的对象,降低了解决问题的复杂度,并且由于Spring默认是单例模式,使得对象可以被灵活地扩展和重用,极大降低了系统的开销。通过IOC容器,实现了具有依赖关系的对象间的解耦



三、IOC的实现原理:


为什么要使用反射

程序运行前需要先编译,编译过程中将代码中需要的类加载到JVM中,运行的时候进行内存分配(类的实例化),相当于加载的类已经是固定的,如果使用静态编译的话,增加某个类的创建需要重新编译整个软件,而使用反射机制(动态编译)则不需要,可以在运行的过程中动态的获取。

无反射技术的工厂模式:

//构造工厂类
//也就是说以后如果我们在添加其他的实例的时候只需要修改工厂类就行了
class Factory{
     public static fruit getInstance(String fruitName){
         fruit f=null;
         if("Apple".equals(fruitName)){
             f=new Apple();
         }
         if("Orange".equals(fruitName)){
             f=new Orange();
         }
         return f;
     }

基于反射技术的工厂模式:

class Factory{
    public static fruit getInstance(String ClassName){
        fruit f=null;
        try{
            f=(fruit)Class.forName(ClassName).newInstance();
        }catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }
}

由上面的代码示例可以看出,反射技术极大提升了代码的灵活性,由于无法知道需要创建的Bean类型,反射技术可以在运行时动态的调用构造方法进行类的动态创建,IOC实现的工厂模式即是使用反射技术,能否在运行时动态创建也是衡量一门语言是否是动态语言的标准。之一(可以查下动态语言和静态语言的区别)。


反射机制的作用


反射技术的优缺点



四、Spring IOC的重要内容

4.1 依赖注入的实现(DI)


4.1.1 注入方式

TextEditor.java

public class TextEditor {
   private SpellChecker spellChecker;
   public TextEditor(SpellChecker spellChecker) {
      System.out.println("Inside TextEditor constructor." );
      this.spellChecker = spellChecker;
   }
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

SpellChecker.java

public class SpellChecker {
   public SpellChecker(){
      System.out.println("Inside SpellChecker constructor." );
   }
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   } 
}

MainApp.java

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");
      TextEditor te = (TextEditor) context.getBean("textEditor");
      te.spellCheck();
   }
}

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-3.0.xsd">

   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor">
      <constructor-arg ref="spellChecker"/>
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
   </bean>

</beans>


TextEditor.java

public class TextEditor{
   private SpellChecker spellChecker;
   // a setter method to inject the dependency.
   public void setSpellChecker(SpellChecker spellChecker) {
      System.out.println("Inside setSpellChecker." );
      this.spellChecker = spellChecker;
   }
   // a getter method to return spellChecker
   public SpellChecker getSpellChecker() {
      return spellChecker;
   }
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

SpellChecker.java

public class SpellChecker {
   public SpellChecker(){
      System.out.println("Inside SpellChecker constructor." );
   }
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   }  
}

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-3.0.xsd">

   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor">
      <property name="spellChecker" ref="spellChecker"/>
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
   </bean>

</beans>


4.1.2 注入配置


4.2 Spring IOC的初始化(Bean的初始化)



五、IOC的优缺点

优点

缺点



六、IOC的源码解析

ClassPathXmlApplicationContext

BeanFactory和ApplicationContext的区别



参考