java框架學習日誌-6(bean做用域和自動裝配)

本章補充bean的做用域和自動裝配java

bean做用域

以前提到能夠用scope來設置單例模式web

<bean id="type" class="cn.dota2.tpye.Type" scope="singleton"></bean>

除此以外還有幾種用法
singleton:單例模式,Spring默認使用單例模式,也是開發中最經常使用的類型。即:加載bean配置文件只能生成類的一個實例,只會new一次。
prototype:多例模式,用到一次就會new一次。由於對象多,因此不會銷燬。
request:應用在web項目中,Spring建立這個類以後,將這個類存到request範圍內。
session:應用在web項目中,Spring建立這個類以後,將這個類存到session範圍內。
globalsession:應用在web項目中,必須在portlet環境下才能使用。即在系統下存入數據後,在其子系統下就不須要從新登陸。
注意默認狀況下bean的做用域是單例。以前我有個疑問,既然是單列,爲何能夠在java代碼中建立兩個實例對象?以下圖spring

ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
        Student student=(Student)ac.getBean("student");
        Student student1=(Student)ac.getBean("student");

其實這裏的getBean獲取的bean都是一個bean。咱們改student的名字,student1的名字也會改變。由於student在容器裏只有一個。session

ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
        Student student=(Student)ac.getBean("student");
        Student student1=(Student)ac.getBean("student");
        student.show();
        student.setName("王五");
        student1.show();


改爲prototype測試

<bean id="student" class="cn.dota2.hero.Student" scope="prototype">
        <property name="name" value="張三"/>
    </bean
ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
        Student student=(Student)ac.getBean("student");
        Student student1=(Student)ac.getBean("student");
        student.show();
        student.setName("王五");
        student.show();
        student1.show();

bean自動裝配

一個bean文件可能須要引用其餘不少bean,這樣配置文件可能會很複雜,全部有了自動裝配來簡化spring。
常規引用this

package cq.school.student;

import cq.school.School;

public class Student {
    School school=null;

    public School getSchool() {
        return school;
    }

    public void setSchool(School school) {
        this.school = school;
    }
    public void show(){
        school.getSchool();
    }
}

bean配置prototype

<bean id="frist" class="cq.school.FristSchool"/>
    <bean id="second" class="cq.school.SecondSchool"/>
    <bean id="student" class="cq.school.student.Student">
        <property name="school" ref="frist"/>

自動裝配有幾種種code

經過byname自動裝配。

<bean id="student" class="cq.school.student.Student" autowire="byName">

這裏的name是Student中的setSchoole中的school。它會在bean容器中尋找name相符合的自動裝配。因此須要更改frist或者second的id或者name。代碼以下xml

<bean id="school" class="cq.school.SecondSchool"/>
    <bean id="student" class="cq.school.student.Student" autowire="byName">


java代碼中給school賦值的方法時setSchool,因此會把id爲school傳給student。對象

經過byType裝配。

<bean  class="cq.school.FristSchool"/>
    <bean  class="cq.school.SecondSchool"/>
    <bean id="student" class="cq.school.student.Student" autowire="byType"/>

和byname類似,會自動尋找類型相符合的裝配,測試一下
報錯緣由是由於一中和二中都是符合類型的,要刪除一個才行,用bytpye裝配須要整個容器只有一個相符合的類型。刪除一個後

<bean  class="cq.school.SecondSchool"/>
    <bean id="student" class="cq.school.student.Student" autowire="byType"/>


若是全部配置都須要用到一種配置方式,能夠在頭文件中加入default-autowire="byName"。或者換成其餘配置方法

<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-2.5.xsd" default-autowire="byName">

consrtuctor注入。

經過構造器注入。適用於bytype得而方式裝配構造器,修改一下student的代碼,去掉set方法,讓它在構造方法裏面設置school。

package cq.school.student;

import cq.school.School;

public class Student {
    School school=null;
    public Student(School school){//修改處
        this.school=school;
    }

    public School getSchool() {
        return school;
    }

    public void show(){
        school.getSchool();
    }
}

自動裝配改爲改爲constructor注入

<?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-2.5.xsd" default-autowire="byName">
    <bean  class="cq.school.SecondSchool"/>
    <bean id="student" class="cq.school.student.Student" autowire="constructor"/>
</beans>

結果同樣。

總結

在配置bean時,有 scope屬性,能夠配置bean做用域,在整合struts2和spring時,須要將action設爲scope=「prototype」;(目前不知道爲啥,反正記住),關於自動裝配,用於減小配置文件。我本身感受自動裝配雖然簡潔了代碼,可是太過簡潔反而不利於閱讀,特別是bytype裝配,bean一旦太多,就容易出bug,並且很差排查。建議少用。

相關文章
相關標籤/搜索