Spring-IOC-學習筆記(2)

通過P命名空間給屬性賦值:

<!-- 需要先導入P命名空間 -->
    <bean id="person4" class="spring.beans.Person" p:name="ben" p:cars-ref="cars"></bean>

bean自動裝配:
SpringIOC容器可以自動裝配Bean,需要在的autowire屬性裏指定自動裝配的模式
byType:根據類型自動裝配,若IOC容器中有多個與目標bean類型一致的bean,在這種情況下,Spring將無法判定哪個bean最合適該屬性,所有不能自動裝配。
byName:根據名稱自動裝配,根據bean的名稱和當前bean的屬性名稱進行自動裝配

<bean id="person5" class="spring.beans.Person" p:name="xiao" autowire="byName"></bean>

bean之間的關係:繼承,依賴
繼承配置:

<!-- 重複的屬性值可以從其他bean繼承,並且重寫寫入的數值會覆蓋繼承的屬性值 -->
    <bean id="car" class="spring.beans.Car">
        <constructor-arg value="audi" index="0"></constructor-arg>
        <constructor-arg value="30.12" index="1"></constructor-arg>
    </bean>
    <bean id="car3" p:speed="132" parent="car"></bean>

子bean從父bean中繼承配置,包括bean的屬性配置,子bean也會覆蓋從父bean繼承的配置
若只是把父bean作爲模版,可以設置<bean>的abstract屬性爲true,這樣Spring不會實例化這個bean
並不是<bean>中的所有屬性都會被繼承,如:autowire、abstract等
也可以忽略父bean的class屬性,讓資bean指定自己的類,但此時abstract必須設爲true

依賴:配置本bean時必須要配置依賴的這個bean,依賴的這個bean可以不用是本bean的屬性
通過depends-on屬性設定bean的前置依賴bean,前置依賴的bean會在本bean實例化之前創建好,如果前置依賴於多個bean,則可以用逗號或空格的方式配置bean名稱。

<bean id="person" class="spring.beans.Person" depends-on="car">
        <property name="name" value="Tom"></property>
    </bean>

bean的作用域:
使用bean的scop屬性配置bean的作用域
singleton:默認值,容器初始化創建bean的實例,在整個容器中只創建一個bean實例,是單例的
prototype:原型的,容器初始化時不創建bean的實例,每次請求時都創建一個bean實例並返回

導入外部屬性文件:
使用${propName}引用屬性文件的屬性

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
    </bean>
    <!-- 導入屬性文件 -->
    <context:property-placeholder location="classpath:db.properties" />

SpEL
Spring表達式語言(SpEL):是一個支持運行時查詢和操作對象圖的強大的表達式語言
語法類似於EL:使用#{…}作爲定界符,所有在框號中的字符都被認爲是SpEL
SpEL爲bean的屬性進行動態賦值提供了便利,可以實現:
1.通過bean的id對bean進行引用
2.調用方法以及引用對象中的屬性
3.計算表達式的值
4.正則表達式的匹配

字面量:

<property name="Tom" value="#{4.2}"></property>
<property name="Tom" value="#{1e4}"></property>
<property name="Tom" value="#{'abc'}"><property name="Tom" value="#{"abc"}"></property>
<property name="Tom" value="#{false}"></property>

SpEL引用bean、屬性和方法
引用其他對象:

<property name="Tom" value="#{person}"></property>

引用其他對象得屬性:

<property name="Tom" value="#{person.name}"></property>

調用其他方法,可以鏈式操作:

<property name="Tom" value="#{person.toString()}"></property>
<property name="Tom" value="#{person.toString().toUpperCase()}"></property>

支持算數運算符:+ - * / ^
加號可用作字符串拼接
比較運算符:== >= <= > <
邏輯運算符:and or not
if-else運算符:? : (三元操作符)
正則表達式:matches
調用靜態方法或靜態屬性:通過T()調用,返回一個Class Object,然後調用相應的方法及屬性:

<property name="Tom" value="#{T(java.Lang.Math).PI}"></property>

Bean的生命週期
IOC容器可以管理bean的生命週期,允許在bean生命週期的特定點執行定製的任務
IOC容器對bean生命週期的管理過程:
1.通過構造器或工廠方法創建bean的實例
2.爲bean的屬性設值和對其他bean的引用
3.調用bean的初始化方法
4.使用bean
5.當容器關閉時,調用bean的銷燬方法
在bean的聲明裏設置init-method和destroy-method屬性指定初始化和銷燬方法

創建bean後置處理器:
bean後置處理器允許在調用初始化方法前後對bean進行額外的處理,對IOC容器中的所有bean實例逐一處理
典型應用:檢查bean屬性的正確性和根據特定的標準更改bean的屬性
對bean後置處理器要實現BeanPostProcessor接口,
並具體提供postProcessAfterInitialization(Object bean, String beanName)和postProcessBeforeInitialization(Object bean, String beanName)方法。
注意:這兩個方法完成後需要返回bean實例,否則bean無法執行初始化方法。可以在以上兩個方法中修改bean或返回新的bean

<!-- 配置bean後置處理器,不需要配置id,IOC容器自動識別是一個BeanPostProcessor-->
    <bean class="spring.beans.MyBeanProcessor"></bean>

通過靜態工廠方法創建bean

將對象創建的過程封裝到靜態方法中。只需簡單調用靜態方法,而不用關心創建對象得細節。
靜態工廠方法類:

public class StaticFactory {
    private static Map<String,Car> cars = new HashMap<String,Car>();

    static {
        cars.put("audi", new Car("aodi",30));
        cars.put("bmw", new Car("bmw",34));
    }
    private static Car getCar(String name) {
        return cars.get(name);
    }
}

配置:

<!-- 靜態工廠配置bean,注意是配置bean實例不是配置靜態工廠方法實例
    class屬性指向靜態工廠方法的全類名 -->
    <bean id="car" class="spring.beans.StaticFactory" factory-method="getCar">
        <constructor-arg value="audi"></constructor-arg>
    </bean>

獲取實例bean:

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans-scop.xml");
        Car car = (Car) ctx.getBean("car");

通過實例工廠方法創建bean

將對象創建的過程封裝到另外一個實例的方法裏
聲明通過實例工廠方法創建bean,在bean的factory-bean屬性裏指定擁有該工廠方法的bean,在factory-method屬性裏指定工廠方法的名稱,使用constructor-arg元素爲工廠方法傳遞方法參數

實例工廠方法類:

public class CarFactory {
    private Map<String,Car> cars = null;
    public CarFactory() {
        cars = new HashMap<String, Car>();
        cars.put("audi", new Car("aodi",30));
    }

    public Car getCar(String name) {
        return cars.get(name);
    }
}

配置:

<!-- 配置工廠實例 -->
    <bean id="carFactory" class="spring.beans.CarFactory"></bean>
    <!-- 通過實例工廠方法配置bean -->
    <bean id="car2" factory-bean="carFactory" factory-method="getCar">
        <constructor-arg value="audi"></constructor-arg>
    </bean>

FactoryBean
需要繼承FactoryBean接口,並具體化接口的三個方法。

public class CarFactoryBean implements FactoryBean {
    private String name;
    public void setName(String name) {
        this.name = name;
    }

    //返回bean對象
    @Override
    public Car getObject() throws Exception {
        // TODO Auto-generated method stub
        return new Car(name,32);
    }
   //返回bean的類型
    @Override
    public Class getObjectType() {
        // TODO Auto-generated method stub
        return Car.class;
    }
    //是否是單實例的
    @Override
    public boolean isSingleton() {
        // TODO Auto-generated method stub
        return true;
    }
}

配置:

<!-- class指向FactoryBean的全類名
    property配置FactoryBean的屬性,但實際返回的實例是getObject()方法返回的類型 -->
    <bean id="car3" class="spring.beans.CarFactoryBean">
        <property name="name" value="audi"></property>
    </bean>

通過註解配置Bean

在classpath中掃描組件
組件掃描:Spring能從classpath下自動掃描、偵測和實例化具有特定註解的組件
特定組件包括:@Component 基本註解,標識了一個守Spring管理的組件
@Respository 標識持久層組件
@Service 標識服務層組件
@Controller 標識表現層組件
對掃描到的組件,Spring有默認的命名策略,使用非限定類名,首字母小寫,也可以在註解中通過value屬性值標識組件

當組件類上使用了特定的註解之後,還需要在Spring的配置文件中聲明<context:component-scan>
base-packge屬性指定一個需要掃描的基類包,Spring會自動掃描這個包及子類包中的所有類,需要掃描多個包用逗號隔開
resource-pattern僅掃描特定的類而非基包下的所有類
<context:include-filter>子節點表示要包含的目標類,需要配合use-default-filters屬性一起使用
<context:exclude-filter>字節點表示要排除的目標類
此兩個子節點可以有若干個

@Repository(“name”) 在註解旁可以使用別名name

<context:component-scan>
——元素會自動註冊AutowireAnnotationBeanPosiProcessor實例,該實例可以自動裝配具有@Autowired、@Resource和@Inject註解的元素

@Autowired
應用於構造器,普通字段,具有參數的方法
若某一屬性允許不被設置,可以設置爲@Autowired註解的required屬性爲false
默認情況下IOC容器存在多個類型兼容的Bean,自動裝配無法工作,可以在@Qualifier註解裏提供選定bean的名稱
@Autowired可以應用在數組類型、集合屬性、Map上,用在Map上時若鍵值爲String,Spring將自動裝配所有於之Map值類型兼容的Bean,此時Bean名稱作爲鍵值。

泛型依賴注入
可以爲子類自動注入與子類對應的泛型類型的成員變量的引用

發佈了69 篇原創文章 · 獲贊 20 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章