国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Spring核心 裝配Bean

wanglu1209 / 2788人閱讀

摘要:它的構造器上添加了注解,這表明當創(chuàng)建的時候,會通過這個構造器來進行實例化并且會傳入一個可設置給類型的通過自動裝配,將一個注入到之中注解不僅能夠用在構造器上,還能用在屬性的方法上。

Spring配置的可選方案

Spring容器負責創(chuàng)建應用程序中的bean并通過DI來協(xié)調這些對象之間的關系。當描述bean如何進行裝配時,Spring具有非常大的靈活性,它提供了三種主要的裝配機制:

在XML中進行顯式配置

在Java中進行顯式配置

隱式的bean發(fā)現(xiàn)機制和自動裝配

盡可能地使用自動配置的機制。顯式配置越少越好。當你必須要顯式配置bean的時候(比如,有些源碼不是由你來
維護的,而當你需要為這些代碼配置bean的時候),推薦使用類型安全并且比XML更加強大的JavaConfig。最后,只有想要使用便利的XML命名空間,并且在JavaConfig中沒有同樣的實現(xiàn)時,才應該使用XML

自動化裝配bean

Spring從兩個角度來實現(xiàn)自動化裝配:

組件掃描(component scanning):Spring會自動發(fā)現(xiàn)應用上下文中所創(chuàng)建的bean

自動裝配(autowiring):Spring自動滿足bean之間的依賴

組件掃描和自動裝配組合在一起就能發(fā)揮出強大的威力,它們能夠將顯式配置降低到最少

創(chuàng)建可被發(fā)現(xiàn)的bean CompactDisc接口在Java中定義了CD的概念
package soundsystem;

public interface CompactDisc
{
    void play();
}

CompactDisc的具體內容并不重要,重要的是你將其定義為一個接口。作為接口,它定義了CD播放器對一盤CD所能進行的操作。它將CD播放器的任意實現(xiàn)與CD本身的耦合降低到了最小的程度

帶有@Component注解的CompactDisc實現(xiàn)類SgtPeppers
package soundsystem;
import org.springframework.stereotype.Component;

@Component
public class SgtPeppers implements CompactDisc
{
    private String title = "Sgt. Pepper"s Lonely Hearts Club Band";
    private String artist = "The Beatles";
    
    public void play()
    {
        System.out.println("Playing" + title + "by" + artist);
    }
}

SgtPeppers類上使用了@Component注解。這個簡單的注解表明SgtPeppers類會作為組件類,并告知Spring要為這個類創(chuàng)建bean。沒有必要顯式配置SgtPeppersbean,因為這個類使用了@Component注解,所以Spring會為你把事情處理妥當

不過,組件掃描默認是不啟用的。我們還需要顯式配置一下Spring,從而命令它去尋找?guī)в蠤Component注解的類,并為其創(chuàng)建bean

@ComponentScan注解啟用了組件掃描

以下程序的配置類展現(xiàn)了完成這項任務的最簡潔配:

package soundsystem;
import org.springframework.context.annotation.componentScan;
import org.springframework.context.annotation.Con;
    
@Component
@ComponentScan
public class CDPlayerConfig{}

類CDPlayerConfig通過Java代碼定義了Spring的裝配規(guī)則。觀察可知,CDPlayerConfig類并沒有顯式地聲明任何bean,只不過它使用了@ComponentScan注解,這個注解能夠在Spring中啟用組件掃描

如果沒有其他配置的話,@ComponentScan默認會掃描與配置類相同的包。因為CDPlayerConfig類位于soundsystem包中,因此Spring將會掃描這個包以及這個包下的所有子包,查找?guī)в蠤Component注解的類。這樣的話,就能發(fā)現(xiàn)CompactDisc,并且會在Spring中自動為其創(chuàng)建一個bean

通過XML啟用組件掃描

如更傾向于使用XML來啟用組件掃描的話,那么可以使用Spring context命名空間的元素。以下程序展示了啟用組件掃描的最簡潔XML配置:



        
    
    

測試組件掃描能夠發(fā)現(xiàn)CompactDisc
package soundsystem;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=CDPlayerConfig.class)
public class CDPlayerTest
{
    @Autowired
    private CompactDisc cd;
    
    @test_139772[test] 
    public void cdShouldNotBeNull()
    {
        assertNotNull(cd);
    }
}

CDPlayerTest使用了Spring的SpringJUnit4ClassRunner,以便在測試開始的時候自動創(chuàng)建Spring的應用上下文。注解@ContextConfiguration會告訴它需要在CDPlayerConfig中加載配置。因為CDPlayerConfig類中包含了@ComponentScan,因此最終的應用上下文中應該包含CompactDiscbean

在測試代碼中有一個CompactDisc類型的屬性,并且這個屬性帶有@Autowired注解,以便于將CompactDiscbean
注入到測試代碼之中。最后,會有一個簡單的測試方法斷言cd屬性不為null。如果它不為null的話,就意味著Spring能夠發(fā)現(xiàn)CompactDisc類,自動在Spring上下文中將其創(chuàng)建為bean并將其注入到測試代碼之中

為組件掃描的bean命名

Spring應用上下文中所有的bean都會給定一個ID。前面的例子中,盡管沒有明確地為SgtPeppersbean設置ID,但Spring會根據(jù)類名為其指定一個ID。具體來講,這個bean所給定的ID為sgtPeppers,也就是將類名的第一個字母變?yōu)樾?/p>

若想為這個bean設置不同的ID,則需將期望的ID作為值傳遞給@Component注解:

@Component("lonelyHeartsClub")
public class SgtPeppers implements CompactDisc
{
    ...
}

另外一種為bean命名的方式,使用Java依賴注入規(guī)范(Java Dependency Injection)中所提供的@Named注解來為bean設置ID:

package soundsystem;
import javax.inject.Named;
@Named("lonelyHeartsClub")
public class SgtPeppers implements CompactDisc
{
    ...
}
設置組件掃描的基礎包

為了指定不同的基礎包,所需要在@ComponentScan的value屬性中指明包的名稱:

@Configuration
@ComponentScan("soundsystem")
public class CDPlayerConfig{}

若需更加清晰地表明你所設置的是基礎包,通過basePackages屬性進行配置:

@Configuration
@ComponentScan(basePackages = "soundsystem")
public class CDPlayerConfig{}

如果需要可以設置多個基礎包,只需要將basePackages屬性設置為要掃描包的一個數(shù)組即可:

@Configuration
@ComponentScan(basePackages = {"soundsystem", “videos”})
public class CDPlayerConfig{}

上面例子中,所設置的基礎包是以String類型表示的。這是可行的,但這種方法是類型不安全(not type-safe)的。如進行代碼重構,那么所指定的基礎包可能會出現(xiàn)錯誤

除了將包設置為簡單的String類型之外,@ComponentScan提供的另外一種方法,將其指定為包中所包含的類或接口:

@Configuration
@ComponentScan(basePackageClasses = {CDPlayer.class, DVDPlayer.class})
public class CDPlayerConfig{}
通過為bean添加注解實現(xiàn)自動裝配

自動裝配就是讓Spring自動滿足bean依賴的一種方法,在滿足依賴的過程中,會在Spring應用上下文中尋找匹配某個bean需求的其他bean。為了聲明要進行自動裝配,我們可以借助Spring的@Autowired注解

下述程序CDPlayer類。它的構造器上添加了@Autowired注解,這表明當Spring創(chuàng)建CDPlayerbean的時候,會通過這個構造器來進行實例化并且會傳入一個可設置給CompactDisc類型的bean

通過自動裝配,將一個CompactDisc注入到CDPlayer之中:

package soundsystem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class CDPlayer implement MediaPlayer
{
    private CompactDisc cd;
    
    @Autowired
    public CDPlayer(CompactDisc cd)
    {
        this.cd = cd;
    }
    
    public void play
    {
        cd.play();
    }
}

@Autowired注解不僅能夠用在構造器上,還能用在屬性的Setter方法上。比如說,如果CDPlayer有一個setCompactDisc()方法,那么可以采用如下的注解形式進行自動裝配:

@Autowired
public void setCompactDisc(CompactDisc cd)

@Autowired注解可以用在類的任何方法上。假設CDPlayer類有一個insertDisc()方法,那么@Autowired能夠像在setCompactDisc()上那樣,發(fā)揮完全相同的作用:

@Autowired
public void insertDisc(CompactDisc cd)
{
    this.cd = cd;
}

不管是構造器、Setter方法還是其他的方法,Spring都會嘗試滿足方法參數(shù)上所聲明的依賴。假如有且只有一個bean匹配依賴需求的話,那么這個bean將會被裝配進來

如果沒有匹配的bean,那么在應用上下文創(chuàng)建的時候,Spring會拋出一個異常。為了避免異常的出現(xiàn),你可以將@Autowired的required屬性設置為false:

@Autowired
public CDPlayer(CompactDisc cd)
{
    this.cd = cd;
}

將required屬性設置為false時,Spring會嘗試執(zhí)行自動裝配,若沒有匹配的bean,Spring將會讓這個bean處于未裝配的狀態(tài)。但把required屬性設置為false時,需要謹慎對待。如果代碼中沒有進行null檢查,處于未裝配狀態(tài)的屬性可能出現(xiàn)NullPointerException

@Autowired是Spring特有的注解。如果不愿代碼中到處使用
Spring的特定注解來完成自動裝配任務,可考慮替換為@Inject:

package soundsystem;
import javax.inject.Inject;
import javax.inject.Named;

@Named
public class CDPlayer
{
    ...
    @Inject
    public CDPlayer(CompactDisc cd)
    {
        this.cd = cd;
    }
    ...
}

@Inject注解來源于Java依賴注入規(guī)范,該規(guī)范同時還定義了@Named注解。在自動裝配中,Spring同時支持@Inject和
@Autowired。盡管@Inject和@Autowired之間有著一些細微的差別,但是在大多數(shù)場景下,是可以互相替換的

驗證自動裝配

除了注入CompactDisc,還將CDPlayerbean注入到測試代碼的player成員變量之中(它是更為通用的MediaPlayer類型)。在play()測試方法中,我們可以調用CDPlayer的play()方法,并斷言它的行為與預期一致

在測試代碼中使用System.out.println()。因此,該樣例中使用了StandardOutputStreamLog,是來源于System Rules庫(http://stefanbirkner.github.i...)的一個JUnit規(guī)則,該規(guī)則能夠基于控制臺的輸出編寫斷言。SgtPeppers.play()方法的輸出將被發(fā)送到控制臺上

通過Java代碼裝配bean

如想將第三方庫中的組件裝配到你的應用中,在這種情況下無法通過在它的類上添加@Component和@Autowired注解的方法實現(xiàn)自動化裝配

JavaConfig與其他的Java代碼存在區(qū)別,在概念上,它與應用程序中的業(yè)務邏輯和領域代碼不同的。盡管都使用相同的語言進行表述,但JavaConfig是配置代碼。這意味著它不應該包含任何業(yè)務邏輯,JavaConfig也不應該侵入到業(yè)務邏輯代碼之中。盡管不是必須的,但通常會將JavaConfig放到多帶帶的包中,使它與其他的應用程序邏輯分離開來,這樣對于它的意圖就不會產生困惑了

創(chuàng)建配置類

創(chuàng)建JavaConfig類的關鍵在于為其添加@Configuration注解,@Configuration注解表明這個類是一個配置類,該類應該包含在Spring應用上下文中如何創(chuàng)建bean的細節(jié)

package soundsystem;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CDPlayerConfig
{
    ...
}

到此為止,都是依賴組件掃描來發(fā)現(xiàn)Spring應該創(chuàng)建的bean。盡管可以同時使用組件掃描和顯式配置,但在本節(jié)更加關注于顯式配置,因此將CDPlayerConfig的@ComponentScan注解移除掉了。移除了@ComponentScan注解,此時的CDPlayerConfig類就沒有任何作用了。如現(xiàn)在運行CDPlayerTest,測試失敗,并出現(xiàn)BeanCreation-Exception異常。測試期望被注入CDPlayer和CompactDisc,但這些bean根本就沒有創(chuàng)建,因為組件掃描不會發(fā)現(xiàn)它們。下一節(jié),將展現(xiàn)如何使用JavaConfig裝配CDPlayer和CompactDisc

聲明簡單的bean

要在JavaConfig中聲明bean,需編寫一個創(chuàng)建所需類型實例的方法,然后給這個方法添加@Bean注解。如下代碼聲明了CompactDisc bean:

@Bean
public CompactDisc sgtPeppers()
{
    return new SgtPeppers();
}

@Bean注解會告訴Spring這個方法將會返回一個對象,該對象要注冊為Spring應用上下文中的bean。方法體中包含了最終產生bean實例的邏輯

默認情況下,bean的ID與帶有@Bean注解的方法名是一樣的。在本例中,bean的名字將會是sgtPeppers。如果你想為其設置成一個不同的名字的話,那么可以重命名該方法,也可以通過name屬性指定一個不同的名字:

@Bean(name= "lonelyHeartsClubBand")
public CompactDisc sgtPeppers()
{
    return new SgtPeppers();
}
借助JavaConfig實現(xiàn)注入

前面所聲明的CompactDisc bean非常簡單,自身沒有其他依賴。現(xiàn)在,需要聲明依賴于CompactDisc的CDPlayer bean。在JavaConfig中裝配bean的最簡單方式就是引用創(chuàng)建bean的方法。如下就是一種聲明CDPlayer的可行方案:

@Bean
public CDPlayer cdPlayer()
{
    return new CDPlayer(sgtPeppers());
}

這個方法會創(chuàng)建一個bean實例并將其注冊到Spring應用上下文中。所創(chuàng)建的bean ID為cdPlayer,與方法的名字相同。cdPlayer()的方法體與sgtPeppers()稍微有些區(qū)別。在這里并沒有使用默認的構造器構建實例,而是調用了需要傳入CompactDisc對象的構造器來創(chuàng)建CDPlayer實例。看起來,CompactDisc是通過調用sgtPeppers()得到的,但情況并非完全如此。因為sgtPeppers()方法上添加了@Bean注解,Spring將會攔截所有對它的調用,并確保直接返回該方法所創(chuàng)建的bean,而不是每次都對其進行實際的調用

@Bean
public CDPlayer cdPlayer()
{
    return new CDPlayer(sgtPeppers());
}
@Bean
public CDPlayer anotherCDPlayer()
{
    return new CDPlayer(sgtPeppers());
}

默認情況下,Spring中的bean都是單例的,并沒必要為第二個CDPlayer bean創(chuàng)建完全相同的SgtPeppers實例。所以,Spring會攔截對sgtPeppers()的調用并確保返回的是Spring所創(chuàng)建的bean,也就是Spring本身在調用sgtPeppers()時所創(chuàng)建的CompactDiscbean。因此,兩個CDPlayer bean會得到相同的SgtPeppers實例

@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc)
{
    return new CDPlayer(sgtPeppers());
}

在這里,cdPlayer()方法請求一個CompactDisc作為參數(shù)。當Spring調用cdPlayer()創(chuàng)建CDPlayerbean的時候,它會自動裝配一個CompactDisc到配置方法之中。然后,方法體就可以按照合適的方式來使用它。借助這種技術,cdPlayer()方法也能夠將CompactDisc注入到CDPlayer的構造器中,而且不用明確引用CompactDisc的@Bean方法

通過這種方式引用其他的bean通常是最佳的選擇,因為它不會要求將CompactDisc聲明到同一個配置類之中。在這里甚至沒有要求CompactDisc必須要在JavaConfig中聲明,實際上它可以通過組件掃描功能自動發(fā)現(xiàn)或者通過XML來進行配置

可以將配置分散到多個配置類、XML文件以及自動掃描和裝配bean之中,只要功能完整健全即可。不管CompactDisc是采用什么方式創(chuàng)建出來的,Spring都會將其傳入到配置方法中,并用來創(chuàng)建CDPlayer bean

通過XML裝配bean 創(chuàng)建XML配置規(guī)范

在使用XML為Spring裝配bean之前,你需要創(chuàng)建一個新的配置規(guī)范。在使用JavaConfig的時候,這意味著要創(chuàng)建一個帶有@Configuration注解的類,而在XML配置中,這意味著要創(chuàng)建一個XML文件,并且要以元素為根



        
    
    

如上基本的XML配置已比同等功能的JavaConfig類復雜。在JavaConfig中只需要@Configuration,但在XML中,需要在配置文件的頂部聲明多個XML模式(XSD)文件,這些文件定義了配置Spring的XML元素

借助Spring Tool Suite創(chuàng)建XML配置文件創(chuàng)建和管理Spring XML配置文件的一種簡便方式是使用Spring Tool Suite(https://spring.io/tools/sts)。在Spring Tool Suite的菜單中,選擇File>New>Spring Bean Configuration File,能夠創(chuàng)建Spring XML配置文件,并且可以選擇可用的配置命名空間

用來裝配bean的最基本的XML元素包含在spring-beans模式之中,在上面這個XML文件中,它被定義為根命名空間。是該模式中的一個元素,它是所有Spring配置文件的根元素

聲明一個簡單的

要在基于XML的Spring配置中聲明一個bean,我們要使用springbeans模式中的另外一個元素:元素類似于JavaConfig中的@Bean注解。可以如下的方式聲明CompactDiscbean:


這里聲明了一個簡單的bean,創(chuàng)建這個bean的類通過class屬性來指定的,并且要使用全限定的類名

因沒明確給定ID,所以這個bean將會根據(jù)全限定類名來進行命名。在本例中,bean的ID將會是“soundsystem.SgtPeppers#0”。其中,“#0”是一個計數(shù)的形式,用來區(qū)分相同類型的其他bean。如果你聲明了另外一個SgtPeppers,并且沒有明確進行標識,那么它自動得到的ID將會是“soundsystem.SgtPeppers#1”

通常來講,更好的辦法是借助id屬性,為每個bean設置一個你自己選擇的名字:

    

減少繁瑣為了減少XML中繁瑣的配置,只對那些需要按名字引用的bean(比如,你需要將對它的引用注入到另外一個bean中)進行明確地命名

借助IDE檢查XML的合法性使用能夠感知Spring功能的IDE,如Spring Tool Suite,能夠在很大程度上幫助你確保Spring XML配置的合法性

借助構造器注入初始化bean

在Spring XML配置中,只有一種聲明bean的方式:使用元素并指定class屬性。Spring會從這里獲取必要的信息來創(chuàng)建bean。但是,在XML中聲明DI時,會有多種可選的配置方案和風格。具體到構造器注入,有兩種基本的配置方案可供選擇:

元素

使用Spring 3.0所引入的c-命名空間

構造器注入bean引用

1.元素方案:
現(xiàn)已聲明SgtPeppers bean,并且SgtPeppers類實現(xiàn)了CompactDisc接口,所以實際上已經(jīng)一個可以注入到CDPlayerbean中的bean。所需做的是在XML中聲明CDPlayer并通過ID引用SgtPeppers:


    

當Spring遇到這個元素時,會創(chuàng)建一個CDPlayer實例。元素會告知Spring要將一個ID
為compactDisc的bean引用傳遞到CDPlayer的構造器中

2.c-命名空間方案:
c-命名空間是在XML中更為簡潔地描述構造器參數(shù)的方式。要使用它的話,必須要在XML的頂部聲明其模式,如下所示:




    
    

    
    
        
        
        
    

    
    

    
    


在c-命名空間和模式聲明之后,就可以使用它來聲明構造器參數(shù)了,如下所示:


    

屬性名以“c:”開頭,也就是命名空間的前綴。接下來就是要裝配的構造器參數(shù)名,在此之后是“-ref”,這是一個命名的約定,它會告訴Spring,正在裝配的是一個bean的引用,這個bean的名字是compactDisc,而不是字面量“compactDisc”

引用參數(shù)的名稱有些怪異,因為需要編譯代碼時,將調試標志(debug symbol)保存在類代碼中。如果優(yōu)化構建過程,將調試標志移除掉,那么這種方式可能就無法正常執(zhí)行。根本不用去標示參數(shù)的方案:



將字面量(literal value)注入到構造器中

迄今為止,所做的DI通常指的都是類型的裝配——也就是將對象的引用裝配到依賴于它們的其他對象之中——而有時需要的只是用一個字面量值來配置對象

1.元素方案:

package soundsystem;
public class BlankDisc implements CompactDisc
{
    private String title;
    private String artist;
    
    public BlankDisc(String title, String artist)
    {
        this.title = title;
        this.artist = artist;
    }
    
    public void play()
    {
        System.out.println("Playing" + title + "by" + artist);
    }
}

    
    

上述程序使用元素進行構造器參數(shù)的注入。沒有使用“ref”屬性來引用其他的bean,而使用了
value屬性,通過該屬性表明給定的值要以字面量的形式注入到構造器之中

2.c-命名空間方案:

引用構造器參數(shù)名:


通過參數(shù)索引裝配相同的字面量值:

               
裝配集合

含有磁道列表概念的BLankDisc

package soundsystem.collections;

import java.ytil.List;
import soundsystem.CompactDisc;

public class BlankDisc implements CompactDisc
{
    private String title;
    private String artist;
    private List tracks;
    
    public BlankDisc(String title, String artist, List tracks)
    {
        this.title = title;
        this.artist = artist;
        this.tracks = tracks;
    }
    
    public void play()
    {
        System.out.println("Playing" + title + "by" + artist);
        for(String track : tracks)
        {
            System.out.println("-Track: " + track);
        }
    }
}

這個變更會對Spring如何配置bean產生影響,在聲明bean時,必須要提供一個磁道列表。較好的解決方法是提供一個磁道名稱的列表。首先,可以使用元素將其聲明為一個列表:


    
    
    
        
            Sgt. Pepper"s Lonely Hearts Club Band
            With a Little Help from My Friend
            Lucy in the Sky with Diamonds
            Getting Better
            Fixing a Hole
            
    
        
        
    

    
    


使用p-命名空間裝配compactDisc屬性:

屬性的名字使用了“p:”前綴,表明我們所設置的是一個屬性。接下來就是要注入的屬性名。最后,屬性的名稱以“-ref”結尾,這會提示Spring要進行裝配的是引用,而不是字面量

將字面量注入到屬性中

以下BlankDisc完全通過屬性注入進行配置,而不是構造器注入。新的BlankDisc類如下所示:

package soundsystem.collections;

import java.ytil.List;
import soundsystem.CompactDisc;

public class BlankDisc implements CompactDisc
{
    private String title;
    private String artist;
    private List tracks;
    
    public setTitle(String title)
    {
        this.title = title;
    }
    
    public setArtistString artist)
    {
        this.artist = artist;
    }
            
    public setTracks(List tracks)
    {
        this.tracks = tracks;
    }
    
    public void play()
    {
        System.out.println("Playing" + title + "by" + artist);
        for(String track : tracks)
        {
            System.out.println("-Track: " + track);
        }
    }
}

借助元素的value屬性裝配這些屬性,內嵌元素設置tracks屬性:


    
    
    
        
            Sgt. Pepper"s Lonely Hearts Club Band
            With a Little Help from My Friend
            Lucy in the Sky with Diamonds
            Getting Better
            Fixing a Hole
            
              
  
最新活動
閱讀需要支付1元查看
<