1. 程式人生 > >Spring 實戰-第二章-裝配Bean

Spring 實戰-第二章-裝配Bean

clu cnblogs filesyste resources 開始 erp hearts 改名 節點

Bean是Spring對象的聲明(裝配wiring),要使用Spring,必須先裝配需要使用的對象,有3種裝配的方式

  1. 自動化裝配Bean
  2. 通過Java代碼裝配
  3. 通過XML裝配
  • 自動化裝配Bean

自動化裝配Bean很簡單

1.聲明接口

package soundsystem;
public interface CompactDisc {
    void play();
}

2.添加註解



package soundsystem;
import org.springframework.stereotype.Component;
@Component
public class SgtPepper implements CompactDisc { private String title ="Sgt. Pepper‘s Lonely Hearts Club Band"; private String artist="The Beatles"; @Override public void play() { System.out.println("Playing "+ title +" by "+artist); } }

@Component表明該類會作為組件類,並告知Spring要為這個類創建Bean。

3.增加配置,用於連接Bean和接口

package soundsystem;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class CDPlayerConfig {

}

@Configuration註解表明這個類是一個配置類,該類應該包含在Spring應用上下文中如何創建Bean的細節。

@ComponentScan能夠在Spring中啟動組件掃描

4.測試

package soundsystem;

import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {
    @Autowired
    private CompactDisc cd;
    @Test
    public void cdShouldNotBeNull(){
        assertNotNull(cd);
    }
}

@Autowired表示會根據配置自動裝配

  • 通過Java代碼裝配Bean

JavaConfig是配置代碼,不應該包含任何業務邏輯,也不應該侵入到業務邏輯代碼中,通常會將JavaConfig放到單獨的包中。

對於CDPlayerConfig稍加改造,去掉@ComponentScan註解,意味著關掉了自動掃描,因此會導致無法發現組件,進而導致失敗,

為了解決這個問題在,在代碼中顯式的聲明Bean,這樣在使用CompactDisc的時候,會根據配置,使用SgtPeppers類進行初始化。

package soundsystem;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CDPlayerConfig {
    @Bean
    public CompactDisc sgtPeppers(){
        return new SgtPepper();
    }
}

CompactDisc結構非常簡單,如果更復雜的結構如何處理呢?

增加MediaPlayer接口

package soundsystem;
public interface MediaPlayer {
    public void play();
}

增加CDPlayer類,實現MediaPlayer接口,CDPlayer中有私有屬性cd,在play動作時,需要調用cd的play方法

package soundsystem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CDPlayer implements MediaPlayer {
    @Autowired
    private CompactDisc cd;

    @Autowired
    public CDPlayer(CompactDisc cd) {
        this.cd=cd;
    }

    @Override
    public void play() {
        cd.play();
    }
}

為了能夠初始化CDPlayer,需要在CDPlayerConfig中增加一個對應的Bean,使用CompactDisc作為參數來初始化CDPlayer

package soundsystem;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CDPlayerConfig {
    @Bean
    public CompactDisc sgtPeppers(){
        return new SgtPepper();
    }
    
    @Bean
    public CDPlayer cdPlayer(CompactDisc compactDisc){
        return new CDPlayer(compactDisc);
    }
}

測試代碼中增加MediaPlayer的測試內容,player增加了Autowired註解,

初始化的時候,會掃描代碼找到可以用的實現(CDPlayer),然後CDPlayer會在CDPLayerConfig(JavaConfig)中找到對應的Bean,並進行初始化

package soundsystem;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {
    @Autowired
    private CompactDisc cd;

    @Autowired
    private MediaPlayer player;

    @Test
    public void playerplay() {
        player.play();
    }

    @Test
    public void cdShouldNotBeNull() {
        assertNotNull(cd);
    }
}
  • 通過XML裝配Bean

spring最初就是通過xml進行配置的,但是對比前面的方法有些缺點,1.配置比較被動,方式比較單一, 2.不靈活,如果改名,可能會導致各種找不到

首先增加一個配置文件,其中使用了spring相關命名空間,在beans節點中,配置需要bean

<?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="compactDisc" class="main.java.soundsystem.SgtPepper"/>
    
</beans>

然後,由於剛開始學習spring,書中代碼並不是很詳實,摸索後,直接使用最暴力的方法,僅供展示通過xml裝配bean

package main.java.soundsystem;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class main {
    @Autowired
    static CompactDisc cd;
    public static void main(String[] args) {

        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                "file:G:\\CtripJavaSource\\SoundSystem\\src\\main\\resources\\testconfig.xml"); // 加載xml文件
        CompactDisc cd = (CompactDisc)ctx.getBean("compactDisc"); // 裝配bean
        cd.play();
    }
}

這裏使用絕對路徑方式加載xml,然後進行裝配並實例化。

spring的目錄結構和配置讀取還不是很清楚,待學習。

Spring 實戰-第二章-裝配Bean