Spring IoC-依賴注入與屬性裝配(1)-概述

概述

對於在容器中的bean而言, 它的工作可能依賴於其他Bean, 比如一臺電腦的工作依賴於鼠標,鍵盤,屏幕和主機. 當我們對每一個Bean完成初始化時候, 需要確定一種裝配方式, 將它所依賴的Bean注入進去.
Spring提供了三種依賴裝配方案:

  • 通過XML來顯式指定裝配值.
  • 通過JavaConfig進行裝配.
  • 通過自動裝配機制.

通過XML顯式配置裝配

使用使用XML來顯式裝配時候, 我們又可以選擇三種方法:

  1. 通過setter來注入屬性值.
  2. 通過構造函數來注入屬性值.
  3. 通過Factory對象來直接注入Bean.

提示: 如果Java中沒有任何構造函數, 則編譯會自動生成一個默認的構造函數.

在XML中使用Setter來實現依賴注入

採用setter注入需要有兩個前提:

  1. 類需要有的無參構造函數.
  2. 類需要有對屬性的設置方法setXxx.

Java代碼:

public class Keyboard {
    private String name;

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

    @Override
    public String toString() {
        return "Keyboard{" +
                "name='" + name + '\'' +
                '}';
    }
}

// 電腦
public class Computer {
    private String name;
    private Keyboard keyboard;

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

    public void setKeyboard(Keyboard keyboard) {
        this.keyboard = keyboard;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "name='" + name + '\'' +
                ", keyboard=" + keyboard +
                '}';
    }
}

    public static void main(String[] args) {
        String path = "classpath:/application-di-computer.xml";
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(path);
        Keyboard keyboard = context.getBean(lab.anoper.ioc.di.computer.component.Keyboard.class);
        System.out.println(keyboard);
        Computer computer = context.getBean(lab.anoper.ioc.di.computer.component.Computer.class);
        System.out.println(computer);
    }

bean定義文件:

<!--通過屬性注入-->
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
       default-autowire="byName">
    <bean id="hpKeyboard" class="lab.anoper.ioc.di.computer.component.Keyboard">
        <!-- 惠普鍵盤 -->
        <property name="name" value="HP"/>
    </bean>

    <bean id="computer" class="lab.anoper.ioc.di.computer.component.Computer">
        <property name="name" value="Walter"/>
        <property name="keyboard" ref="hpKeyboard"/>
    </bean>
</beans>

輸出結果:

Keyboard{name='HP'}
Computer{name='Walter', keyboard=Keyboard{name='HP'}}

在XML中使用構造方法注入

使用構造函數注入需要有一個前提: 有相應的構造函數. 如果我們使用第三方時候, 並沒有提供setXxx方法時候, 可以使用構造函數注入.

java代碼:

public class Keyboard {
    private String name;

    public Keyboard(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Keyboard{" +
                "name='" + name + '\'' +
                '}';
    }
}

public class Computer {
    private String name;
    private Keyboard keyboard;

    public Computer(String name, Keyboard keyboard) {
        this.name = name;
        this.keyboard = keyboard;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "name='" + name + '\'' +
                ", keyboard=" + keyboard +
                '}';
    }
}

public class DIDemo {
    public static void main(String[] args) {
        String path = "classpath:/application-di-computer-cons.xml";
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(path);
        Keyboard keyboard = context.getBean(lab.anoper.ioc.di.computer.component.Keyboard.class);
        System.out.println(keyboard);
        Computer computer = context.getBean(lab.anoper.ioc.di.computer.component.Computer.class);
        System.out.println(computer);
    }
}

配置文件:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
       default-autowire="byName">
    <bean id="hpKeyboard" class="lab.anoper.ioc.di.computer.component.Keyboard">
        <constructor-arg value="HP"/>
    </bean>

    <bean id="computer" class="lab.anoper.ioc.di.computer.component.Computer">
        <constructor-arg value="Walter"/>
        <constructor-arg ref="hpKeyboard"/>
    </bean>
</beans>

輸出結果:

Keyboard{name='HP'}
Computer{name='Walter', keyboard=Keyboard{name='HP'}}

使用JavaConfig顯式裝配依賴

如果要是用JavaConfig顯式裝配依賴, 則需要使用@Configuration, @Bean等註解.

  • @Configuration: 用於指示這個類中存在一個或者多個bean, 並且這些bean可以由Spring容器管理.
  • @Bean: 指示這個方法會產生一個可以由Spring容器管理的bean.

Java代碼:

@Configuration
public class ComputerConfig {
    @Bean
    public Keyboard keyboard () {
        return new Keyboard("HP");
    }

    @Bean
    public Computer computer() {
        return new Computer("Walter", keyboard());
    }
}

public class DIDemo {
    public static void main(String[] args) {
        String scanPackages = "lab.anoper.ioc.di.computer.config";
        // 指定要掃描的包
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(scanPackages);
        Computer computer = context.getBean("computer", lab.anoper.ioc.di.computer.component.Computer.class);
        System.out.println(computer);
    }
}

運行結果:

Computer{name='Walter', keyboard=Keyboard{name='HP'}}

使用自動裝配注入依賴

使用自動裝配主要依賴於autowired註解來實現, 這個註解可以註解在屬性上, setter方法上或者構造函數上. 註解在setter上或者是屬性上, 最終將會採用setter注入方法.註解在構造函數上, 最終會採用構造函數注入方法.
需要使用到如下註解:

  • @Component: 指示此類是一個"組件", 當自動掃描時候, 將會被視爲一個候選.
  • @Autowired: 將構造函數,字段,setter方法或config方法標記爲由Spring的依賴項注入工具自動裝配.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章