天天看點

Spring5參考指南:Bean的建立

文章目錄

    • Spring容器中的Bean
    • Bean的命名
    • Bean的執行個體化

Bean在Spring中就是一個業務元件,我們通過建立各種Bean來完成最終的業務邏輯功能。

在容器内部,每個bean的定義可以被表示為BeanDefinition,通過BeanDefinition可以獲得bean的很多資訊包括:包名,bean的作用域,生命周期,bean的引用和依賴等。

通過ApplicationContext的getBeanFactory()方法,能夠獲得DefaultListableBeanFactory的實作。實作類有兩個方法可以将使用者自定義的bean注冊到Spring容器中。兩個方法是:

  • registerSingleton(String beanName, Object singletonObject)
  • registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

其中,registerSingleton通過bean名字,和bean執行個體在注冊。registerBeanDefinition則通過bean名字和beanDefinition來注冊。

如果想自己建構beanDefinition比較麻煩,他需要實作的方法比較多。

使用方式如下:

// create and configure beans
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

//從ApplicationContext 中擷取 DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory=(DefaultListableBeanFactory)context.getBeanFactory();

BeanDefinition beanDefinition=beanFactory.getBeanDefinition("daoA");

System.out.println(beanDefinition.getBeanClassName());

    DaoC daoC=new DaoC();
 //将daoC注冊到spring容器中
   beanFactory.registerSingleton("daoC", daoC);

 //也可以注冊beanDefinition
// beanFactory.registerBeanDefinition();

//從Spring容器中擷取到剛剛手動注冊的bean
System.out.println(context.getBean("daoC"));      

Bean可以通過id和name屬性來命名,id是全局唯一的,name可以有多個,可以通過逗号,分号或者空格來區分多個name。

當然id和name不是必須的,如果你不指定bean的标志符,SPring容器會為你自動配置設定一個。這種沒有名字的Bean一般用在内部bean或者自動裝載的情況。

bean命名一般采用開頭小寫的駝峰模式。如:accountManager, accountService, userDao, loginController等。

使用也可以為bean定義别名,一般用在大型系統中,将引入的外部bean和自身的系統命名保持一緻。

<alias name="myApp-dataSource" alias="subsystemA-dataSource"/>
<alias name="myApp-dataSource" alias="subsystemB-dataSource"/>      

如果你使用Java配置,那麼可以使用@Bean來為Bean命名。

執行個體化bean一般有3種方式,通過構造函數執行個體化,通過靜态工程方法執行個體化,通過執行個體的工廠方法執行個體化。

一般來說我們使用構造函數在Spring容器中建立bean。這個和用new建立bean并将其注入到Spring容器中在本質上是一樣的。

工廠方法用的比較少,如果我們需要每次生成一個新的對象時候,就可以考慮使用工廠方法了。工廠方法在後面的作用域範圍一文中,我們還會詳細的講解怎麼使用。

構造函數執行個體化

在Spring中,bean的構造函數跟普通構造函數沒有什麼差別,最常見的就是無參構造函數:

<bean id="exampleBean" class="examples.ExampleBean"/>      

當然也可以建立帶參數的構造函數:

    <bean id="petStore" class="com.flydean.services.PetStoreService">
        <constructor-arg ref="accountDao"/>
    </bean>      

靜态工廠方法

靜态工廠方法通過class屬性指定包含靜态工廠方法的類,使用名為factory-method的屬性指定工廠方法本身的名稱。

這個指定的方法用來傳回需要的執行個體。

    <!-- factory method -->
    <bean id="clientService"
          class="com.flydean.services.ClientService"
          factory-method="createInstance"/>      

ClientService的代碼如下:

public class ClientService {
    private static ClientService clientService = new ClientService();
    private ClientService() {}

    /**
     * 工廠方法,必須是靜态方法
     * @return
     */
    public static ClientService createInstance() {
        return clientService;
    }
}      

大家注意,這裡的createInstance方法必須是靜态的。

執行個體工廠方法

和靜态工廠方法一樣,執行個體工廠方法隻不過是使用執行個體中的方法來建立相應的bean對象。

這樣在factory-bean定義工廠bean執行個體,在factory-method中定義需要建立bean的方法:

    <!--factory bean-->
    <bean id="serviceLocator" class="com.flydean.services.DefaultServiceLocator">
    </bean>

    <bean id="serviceA"
          factory-bean="serviceLocator"
          factory-method="createServiceAInstance"/>

    <bean id="serviceB"
          factory-bean="serviceLocator"
          factory-method="createServiceBInstance"/>      

DefaultServiceLocator代碼如下:

public class DefaultServiceLocator {

    private static ServiceA serviceA = new ServiceA();

    private static ServiceB serviceB = new ServiceB();

    public ServiceA createServiceAInstance() {
        return serviceA;
    }

    public ServiceB createServiceBInstance() {
        return serviceB;
    }
}      
  • 區塊鍊從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特币等持續更新
  • Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
  • Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
  • java程式員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程