1. 程式人生 > >Spring第二篇和第三篇的補充【JavaConfig配置、c名稱空間、裝載集合、JavaConfig與XML組合】

Spring第二篇和第三篇的補充【JavaConfig配置、c名稱空間、裝載集合、JavaConfig與XML組合】

前言

在寫完Spring第二和第三篇後,去讀了Spring In Action這本書…發現有知識點要補充,知識點跨越了第二和第三篇,因此專門再開一篇博文來寫…

通過java程式碼配置bean

由於Spring的自動裝配並不能將第三方庫元件裝配到應用中,於是需要顯式裝配配置。顯示裝配有兩種方式

  • 通過java程式碼裝配bean
  • 通過XML裝配bean

Spring In Action作者首推使用自動裝配的功能,而後是通過java程式碼配置bean,最後才用XML檔案配置的方式..

那麼怎麼通過java程式碼來配置Bean呢??

  • 編寫一個java類,使用@Configuration修飾該類
  • 被@Configuration修飾的類就是配置類

編寫配置類


    @org.springframework.context.annotation.Configuration
    public class Configuration {

    }

使用配置類建立bean

  • 使用@Bean來修飾方法,該方法返回一個物件。
  • 不管方法體內的物件是怎麼建立的,Spring可以獲取得到物件就行了。
  • Spring內部會將該物件加入到Spring容器中
  • 容器中bean的ID預設為方法名



@org.springframework.context.annotation.Configuration
public
class Configuration { @Bean public UserDao userDao() { UserDao userDao = new UserDao(); System.out.println("我是在configuration中的"+userDao); return userDao; } }
  • 測試程式碼:要使用@ContextConfiguration載入配置類的資訊【引入test包】

package bb;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.test.context.ContextConfiguration; /** * Created by ozc on 2017/5/11. */ //載入配置類的資訊 @ContextConfiguration(classes = Configuration.class) public class Test2 { @Test public void test33() { ApplicationContext ac = new ClassPathXmlApplicationContext("bb/bean.xml"); UserDao userDao = (UserDao) ac.getBean("userDao"); System.out.println(userDao); } }

這裡寫圖片描述

使用配置類實現物件依賴

Spring in Action有兩種方法(但我測試不出來,如果會的請在評論去告訴我.….)

  • 第一種(測試不出來)

import org.springframework.context.annotation.Bean;

@org.springframework.context.annotation.Configuration
public class Configuration {

    @Bean()
    public UserDao userDao() {

        return new UserDao();
    }

    @Bean
    public UserService userService() {

        //直接呼叫@bean的方法
        return new UserService(userDao());
    }

}
  • 第二種(測試不出來)

import org.springframework.context.annotation.Bean;

@org.springframework.context.annotation.Configuration
public class Configuration {

    @Bean()
    public UserDao userDao() {

        return new UserDao();
    }

    @Bean
    public UserService userService(UserDao userDao) {

        //通過建構函式依賴注入
        return new UserService(userDao);
    }

}

這裡寫圖片描述

  • 如果我直接通過構造器傳入的話,那麼報錯了

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;

@org.springframework.context.annotation.Configuration
public class Configuration {

    @Bean()
    public UserDao userDao() {

        return new UserDao();
    }

    @Bean(autowire = Autowire.BY_TYPE)
    public UserService userService(UserDao userDao) {

        return new UserService(userDao);
    }

}

這裡寫圖片描述

  • 我測試中只有通過這種方法才能拿到userDao的引用。
public class Configuration {

    @Bean()
    public UserDao userDao() {

        return new UserDao();
    }

    @Bean(autowire = Autowire.BY_TYPE)
    public UserService userService() {

        return new UserService(userDao());
    }

}

這裡寫圖片描述

當然了,最簡單直觀的方法還有一種:在UserService中加入setUser()方法,那麼只要set進去就行了..

  • UserService

public class UserService {

    private UserDao userDao ;

    public UserService() {
    }

    public UserService(UserDao userDao) {


    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}
  • Config

import org.springframework.context.annotation.Bean;

@org.springframework.context.annotation.Configuration
public class Config1 {

    @Bean(name = "userDao")
    public UserDao userDao() {

        return new UserDao();
    }


    @Bean(name="userService")
    public UserService userService() {

        UserService userService = new UserService();

        userService.setUserDao(userDao());

        return userService;
    }

}

這裡寫圖片描述

c名稱空間

我們在使用XML配置建立Bean的時候,如果該Bean有構造器,那麼我們使用<constructor-arg>這個節點來對構造器的引數進行賦值…

<constructor-arg>未免有點太長了,為了簡化配置,Spring來提供了c名稱空間,其實和我們之前講到的p名稱空間是一樣的…

要想c名稱空間是需要匯入xmlns:c="http://www.springframework.org/schema/c"


    <bean id="userService" class="bb.UserService" c:userDao-ref="">

    </bean>

c名稱空間有個缺點:不能裝配集合,當我們要裝配集合的時候還是需要<constructor-arg>這個節點

裝載集合

如果物件上的屬性或者建構函式擁有集合的時候,而我們又需要為集合賦值,那麼怎麼辦?

  • 在建構函式上,普通型別

    <bean id="userService" class="bb.UserService" >
        <constructor-arg >
            <list>
                //普通型別
                <value></value>
            </list>
        </constructor-arg>
    </bean>
  • 在屬性上,引用型別

     <property name="userDao">

         <list>
             <ref></ref>
         </list>
     </property>

JavaConfig與XML組合

我們有的時候可能會兩種配置混合時候…

如果JavaConfig的配置類是分散的,我們一般再建立一個更高階的配置類(root),然後使用@Import來將配置類進行組合

如果XML的配置檔案是分散的,我們也是建立一個更高階的配置檔案(root),然後使用來將配置檔案組合

在JavaConfig引用XML

  • 使用@ImportResource()

在XML引用JavaConfig

  • 使用<bean>節點就行了