1. 程式人生 > >先碼後看 spring配置bean的幾種方式:xml直接配置、靜態工廠、例項工廠、factory bean、註解 侵立刪

先碼後看 spring配置bean的幾種方式:xml直接配置、靜態工廠、例項工廠、factory bean、註解 侵立刪

轉自:http://blog.csdn.net/love___code/article/details/53167138

spring框架的核心在於“Ioc控制反轉”“DI依賴注入”以及“AOP面向切面程式設計”,所以在實現這些核心是最基礎的一步即為在ioc容器中配置bean標籤,因為我們獲取物件是通過獲取bean 來獲得的,所以配置好bean,要用物件時我們才能想用就拿.今天查看了一下資料,總結了以下三種方式來配置Bean.(自己定義成三種的,每個人按照自己不同標準可以劃分很多種的

首先先看一下準備的示例類: 
1.一個Hello實體類,定義了name和person屬性 
2.一個Person實體類定義了name屬性 
(注:這裡之所以提供兩個實體類,是為了體現DI依賴注入的特性,這也是配置bean 中非常重要的一點) 
3.測試類–junit下面做的測試 
4.其他類–根據不同的方法來建立

//Hello類
package com.yc.spring;

import org.springframework.beans.factory.annotation.Autowired;

public class Hello {
    private String name;
    /* @Autowired//自動注入物件 */
    private Person person;

    public Hello() {
        System.out.println("我是hello的構造方法");
    }

    public Hello(String name, Person person) {
        super();
        this
.name = name; this.person = person; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public
void sayHello() { System.out.println(String.format("%s 對 %s說你好帥!!!", name, person.getname())); } }
Person類,person作為Hello類的一個屬性,所以Hello類依賴於Person類
package com.yc.spring;

public class Person {
    String name;
    @Override
    public String toString() {
        return "Person [name=" + name + "]";
    }
    public Person(String name) {
        this.name = name;
    }
    public Person() {

    }
    public String getname() {
        return name;
    }
    public void setname(String name) {
        this.name = name;
    }
}
//測試類
package com.yc.spring;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloTest {
    @Test
    public void testHelloStaticFactory(){
        ApplicationContext cxt=new ClassPathXmlApplicationContext("spring.xml");
        System.out.println("==========");
        Hello h01=(Hello) cxt.getBean("填寫待測試的bean  id");
        System.out.println(h01);
        h01.sayHello();
        //(取到hello物件並呼叫sayhello方法)

    }
}

第一種方式:通過編寫xml方式直接配置bean; 
以下程式碼均在spring.xml的配置檔案中編寫:

<!-- xml方式配置bean  -->
        <bean id="per6" class="com.yc.spring.Hello">
                <property name="name" value="小滿"></property>
                <property name="person" ref="per6_1"></property>
        </bean>
        <!-- 建立Hello物件,通過ref引用依賴Person 類 -->
        <bean id="per6_1" class="com.yc.spring.Person">
                <property name="name" value="小欽"></property>
        </bean>

    執行結果:我是hello的構造方法
                ==========
            [email protected]
            小滿 對 小欽說你好帥!!!

第二種方式:通過工廠方式配置bean(工廠方式也就可以理解為,我們事先把我們要獲獲取的物件存放到工廠裡,當我們要用的時候我們就直接通過載入工廠去獲取我們想要的物件) 
工廠方式又分為:靜態工廠和例項工廠 
2.1通過靜態工廠方式配置bean(靜態工廠,就是將我們的物件直接放在一個靜態區裡面,想用的時候我們可以直接呼叫就行)

//建立一個工廠類
package com.yc.spring;

import java.util.HashMap;
import java.util.Map;

public class HelloStaicFactory {
        private static Map<Integer, Hello> map=new HashMap<Integer, Hello>();
        static{
            map.put(1,new Hello("小有",new Person("小瑤")));
            //如果這裡有多個物件要傳入的話,就可以根據鍵來檢索了
        }//將我們的物件都存放到工廠裡面去,而且都是靜態的,可以隨時呼叫

        public static Hello getHello(int id){
            return map.get(id);
        }//對外提供獲取介面,根據id獲得物件
}

//一下是spring.xml中的程式碼
<!--  通過靜態工廠方法來配置bean,注意不是配置靜態工廠方法例項,而是配置bean例項 
       class屬性:指向靜態工廠方法的全類名
      factory-method:指向靜態工廠方法的名字
      constructor-arg:如果靜態工廠方法需要傳入引數,則使用constructor-arg來配置引數
  -->
     <bean id="per1" class="com.yc.spring.HelloStaicFactory" factory-method="getHello">
      <constructor-arg value="1"></constructor-arg>           
    </bean>

    //測試結果:
    ==========
    com.yc.spring.[email protected]17864c4
    小有 對 小瑤說你好帥!!!

2.2通過例項工廠方式配置bean,例項工廠與靜態工廠的區別在於一個是靜態的,可直接呼叫的,一個是需要先例項化工廠,在獲取工廠裡面的物件的

package com.yc.spring;
import java.util.HashMap;
import java.util.Map;
public class HelloInstanceFactory {
        private  Map<Integer, Hello> map;       
            public HelloInstanceFactory(){
                map=new HashMap<Integer, Hello>();
                map.put(4, new Hello("小橋",new Person("小躋")));               
            }
            public Hello getHello(int id){
                return map.get(id);
            }
}

//一下是spring.xml檔案程式碼
<!-- 22通過例項工廠方法來配置bean 
         factory-bean:指向例項工廠方法的bean
         factory-method:指向例項工廠方法的名字
        constructor-arg:如果例項工廠方法需要傳入引數,則使用constructor-arg來配置引數
     -->     
         <bean id="personFactory" class="com.yc.spring.HelloInstanceFactory"></bean>
            <bean id="per4" factory-bean="personFactory" factory-method="getHello">
         <constructor-arg value="4"></constructor-arg>
          </bean> 

執行結果:我是hello的構造方法
        ==========
        com.yc.spring.[email protected]5d53c3
        小橋 對 小躋說你好帥!!!

2.3通過實現factoryBean方法來配置bean–(小編是在不想分太多類了,就勉強載入工廠這裡面了,望見諒)

package com.yc.spring;

import org.springframework.beans.factory.FactoryBean;
//通過實現FactoryBean 介面
public class HelloFactoryBean  implements FactoryBean<Hello>{
    private int id;//講道理,我現在還沒理解這個id是幹嘛用的,等博主知道之後再來修改,大家可自動忽略這裡
    public void setId(int id) {
        this.id = id;
    }
    @Override
    public Hello getObject() throws Exception {
            return new Hello("小發",new Person("小榮"));
    }
    @Override
    public Class<?> getObjectType() {
            return Person.class;
    }
    @Override
    public boolean isSingleton() {  //選擇是否只調用一次建構函式,也就是多個物件的地址是否相同
        return true;
    }

}
    //一下是spring.xml中的程式碼
    <!--2-3  通過實現FactoryBean方法來配置bean
         通過Factorybean來配置bean的例項
            class:指向Factorybean的全類名
           property:配置Factorybean的屬性
         但實際返回的例項卻是Factorybean的getObject()方法返回的例項
     -->
    <bean id="per5" class="com.yc.spring.HelloFactoryBean">
        <property name="id" value="1"></property>
    </bean>
執行結果:
    我是hello的構造方法
    ==========
    [email protected]
    小發 對 小榮說你好帥!!!

第三種方式:通過註解方式(也是目前使用非常廣泛的一種,至少我覺得比以上方便多了)

package com.yc.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component("hello")
//@component(把普通pojo例項化到spring容器中,相當於配置檔案中的<bean id="hello" class="com.yc.spring.Hello"/>)
@Scope("prototype")//原型物件,預設為單例物件,選擇會執行幾次建構函式。這裡選擇是,每次獲取新物件都會執行一次建構函式,物件地址都不同。
public class Hello {
        private String name="小丹";
        @Autowired//自動注入物件,這個註解就是spring可以自動幫你把bean裡面引用的物件的bean,相當於ref的作用
        private Person person;
        public Hello() {
            System.out.println("我是hello的構造方法");
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }

        public Person getPerson() {
            return person;
        }

        public void setPerson(Person person) {
            this.person = person;
        }

        public void sayHello(){
            System.out.println(String.format("%s 對 %s說你好帥!!!",name,person.getname()));
        }   
}

package com.yc.spring;

import org.springframework.stereotype.Component;

@Component("person")//將person物件也載入到spring容器類
public class Person {
        String name="小州";       
        @Override
        public String toString() {
            return "Person [name=" + name + "]";
        }       
        public Person(String name) {
            super();
            this.name = name;
        }
        public Person() {

        }

        public String getname() {
            return name;
        }

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

}
//以下為spring.xml中程式碼
<!-- bean就由spring容器建立好的物件 -->
    <!-- 指定可以做為spring容器管理的物件的包 -->
    <context:component-scan base-package="com.yc.spring"/>

執行結果:
我是hello的構造方法
com.yc.spring.Hello@d5ba3a
小丹 對 小州說你好帥!!!

以上即為配置bean的三種方式,個人感覺註解的最為輕鬆