日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線(xiàn)咨詢(xún)客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

做JAVA的基本上都用過(guò)Spring,而IoC是Spring最核心的模塊之一。那IoC具體有什么用,Spring又是如何做到IoC的呢?這是本文要探索的話(huà)題。

關(guān)于IoC

什么是依賴(lài)?

首先我們要明確“依賴(lài)”的概念。所謂依賴(lài),說(shuō)直白點(diǎn)就是:A用了B,那A就依賴(lài)B。換成程序世界的說(shuō)法,如果A類(lèi)里面出現(xiàn)了B類(lèi)有關(guān)的代碼(刪除B類(lèi),編譯A類(lèi)會(huì)報(bào)錯(cuò)),那A就依賴(lài)B。

打個(gè)比方,如果員工小明上班需要乘坐公交車(chē),從家里到公司,那小明就依賴(lài)了公交車(chē)。抽象成代碼大概是這樣:

public class Worker() {
    private String name;
    private String home;
    private String office;
    // 這里依賴(lài)了Bus類(lèi)
    private Bus bus = new Bus();
    
    public void goToWork() {
        bus.take(name, home, office);
    }
}
復(fù)制代碼

我們知道,依賴(lài)是一種耦合,而過(guò)多的耦合對(duì)程序是有害的,代碼架構(gòu)的本質(zhì),就是盡量去降低耦合。試想一下,如果有一天員工小明升職加薪了,自己買(mǎi)了一輛小轎車(chē)代步,那凡是用到公交車(chē)的地方(比如上班、下班、接孩子、去商場(chǎng)、回家等等)豈不是需要修改代碼,把Bus換成Car?如果某一天又想步行或者騎自行車(chē)呢?

關(guān)于Spring IoC的那些事

 

依賴(lài)倒置原則

有了上面這個(gè)耦合的問(wèn)題,于是業(yè)界的大佬們就想辦法來(lái)解決這個(gè)問(wèn)題。設(shè)計(jì)模式六大原則里面有一個(gè)依賴(lài)倒置原則(Dependence Inversion Principle)。

所謂依賴(lài)倒置原則,就是把原本耦合的A和B分開(kāi),中間加一個(gè)“抽象層”。這樣A只需要依賴(lài)抽象層,并不需要關(guān)心具體實(shí)現(xiàn),只要它能完成自己需要的功能就行了。而B(niǎo)也只依賴(lài)抽象層,實(shí)現(xiàn)這個(gè)功能就行了。

如果A依賴(lài)B,我們稱(chēng)A為“上層”,B為“下層”,依賴(lài)倒置原則強(qiáng)調(diào)上層模塊不應(yīng)該依賴(lài)下層模塊,兩者應(yīng)依賴(lài)其抽象

關(guān)于Spring IoC的那些事

 

仍然是上面員工小明的例子,其實(shí)他上班需要的并不是一個(gè)公交車(chē),而是一個(gè)“交通工具”,這個(gè)交通工具可以是自行車(chē)、電動(dòng)車(chē)、汽車(chē)等等,只要它能夠把小明從家里帶到公司就可以了。我們改一下代碼,變成了這樣:

// 定義抽象類(lèi)
public interface Vehicle {
    void take(String name, String home, String office)
}

// 下層模塊的細(xì)節(jié),依賴(lài)抽象
public class Bus implements Vehicle {
    
    @Override
    public void take(String name, String home, String office) {
        // 實(shí)現(xiàn)細(xì)節(jié)
    }
}

public class Worker() {
    private String name;
    private String home;
    private String office;
    // 上層依賴(lài)了抽象類(lèi)Vehicle
    private Vehicle vehicle = new Bus();
    
    public void goToWork() {
        vehicle.take(name, home, office);
    }
} 

復(fù)制代碼

看到這段代碼也許你會(huì)問(wèn):那這里Worker類(lèi)里面不是還是要new一個(gè)Bus嗎?那還是依賴(lài)了呀,以后如果換成其它交通工具仍然需要改代碼。

別急,這就是我們下面會(huì)講到的控制反轉(zhuǎn)要解決的問(wèn)題。

控制反轉(zhuǎn)

控制反轉(zhuǎn)(Inversion of Control)也就是我們說(shuō)的IoC了。要理解IoC,需要弄清楚到底什么被反轉(zhuǎn)了?如何反轉(zhuǎn)的?

上面的示例代碼我們可以看到,即使我們引入了一個(gè)抽象層,但當(dāng)一個(gè)Worker對(duì)象實(shí)際要使用Vehicle的時(shí)候,它還是必須得創(chuàng)建一個(gè)具體的對(duì)象,它可能是一個(gè)Bus,也可能是一個(gè)Car等。但這樣造成的問(wèn)題是,依賴(lài)沒(méi)有被徹底分離,兩者還是存在耦合。

那如何把它們徹底分離呢?答案就是把創(chuàng)建具體的Vehicle對(duì)象交給第三方去做。這樣Worker不用管如何創(chuàng)建的交通工具,而B(niǎo)us也不用管自己是如何被創(chuàng)建的。

想想我們生活中就有這樣的例子,員工小明要坐公交車(chē),他不用每次都自己去造一輛公交車(chē)吧,只需要去公交車(chē)站,等公交車(chē)公司的調(diào)度就行了。而公交車(chē)工廠也跟小明沒(méi)有任何關(guān)系,它的職責(zé)就是生產(chǎn)好公交車(chē),交付給公交車(chē)公司。通過(guò)引入了“公交車(chē)公司”這個(gè)第三方,小明和公交車(chē)工廠就完全解耦了。

反轉(zhuǎn)的是什么?對(duì)象如何獲取它的依賴(lài)對(duì)象這件事情上,控制權(quán)反轉(zhuǎn)了。從自己創(chuàng)建,反轉(zhuǎn)成了第三方管理。

控制反轉(zhuǎn)的進(jìn)一步含義,不僅僅是獲取,還有整個(gè)要依賴(lài)對(duì)象的生命周期(包括創(chuàng)建、維護(hù)、銷(xiāo)毀等),控制權(quán)都被反轉(zhuǎn)了。

從代碼設(shè)計(jì)來(lái)看,一個(gè)簡(jiǎn)單的解決方式是,把具體的對(duì)象通過(guò)方法參數(shù)傳進(jìn)來(lái),這樣就不強(qiáng)依賴(lài)了:

public class Worker() {
    private String name;
    private String home;
    private String office;
    
    // 通過(guò)方法傳進(jìn)來(lái)
    public void goToWork(Vehicle vehicle) {
        vehicle.take(name, home, office);
    }
} 
復(fù)制代碼

但這樣會(huì)帶來(lái)一個(gè)問(wèn)題,就是給調(diào)用端帶來(lái)了麻煩,相當(dāng)于把對(duì)Bus的依賴(lài),從Worker類(lèi)轉(zhuǎn)移到了它的調(diào)用端,那它的調(diào)用端也會(huì)強(qiáng)依賴(lài)Bus,這本不屬于調(diào)用端的職責(zé),所以沒(méi)有從根本上解決問(wèn)題。而且每次調(diào)用都要傳一個(gè)Vehicle對(duì)象進(jìn)來(lái),很不合理,管理對(duì)象也比較麻煩。

那你可能會(huì)想,我搞個(gè)第三方容器不就行了嗎,這樣每次去第三方容器里面拿:

public class Worker() {
    private String name;
    private String home;
    private String office;
    // 第三方容器
    private VehicleContainer container;
    
    // 通過(guò)容器取
    public void goToWork() {
        container.getTodayVehicle().take(name, home, office);
    }
} 
復(fù)制代碼
關(guān)于Spring IoC的那些事

 

這樣當(dāng)然也能解決,但不是最優(yōu)雅的解決方案,因?yàn)槟忝總€(gè)Bean都需要依賴(lài)Container。那我們能不能Worker類(lèi)不依賴(lài)任何東西,包括Container,實(shí)現(xiàn)上班這個(gè)功能呢?當(dāng)然可以,且聽(tīng)下文分析。

依賴(lài)注入

更優(yōu)雅的方案就是使用依賴(lài)注入(Dependency Injection)。我不想使用Container,每次還要主動(dòng)去拿。我想在自己被創(chuàng)建的時(shí)候(或者創(chuàng)建后),我所依賴(lài)的對(duì)象就自動(dòng)被設(shè)置好了。

關(guān)于Spring IoC的那些事

 

同時(shí),這還是一種“無(wú)侵入”的方式,我們的業(yè)務(wù)代碼里面可以不用寫(xiě)任何關(guān)于IoC的代碼。這樣即使我們某一天換了IoC框架,我們的代碼也不需要做任何修改。

實(shí)現(xiàn)依賴(lài)注入大概有三種方式:構(gòu)造器注入,方法注入和屬性注入。

構(gòu)造器注入

顧名思義,就是通過(guò)構(gòu)造器的方式,把依賴(lài)的對(duì)象注入進(jìn)來(lái)。這樣在new一個(gè)對(duì)象的時(shí)候,就完成了它依賴(lài)的對(duì)象的裝配。

public class Worker() {
    private String name;
    private String home;
    private String office;
    private Vehicle vehicle;
    
    // 通過(guò)構(gòu)造器把要依賴(lài)的對(duì)象傳進(jìn)來(lái)
    public Worker(Vehicle vehicle) {
        this.vehicle = vehicle;
    }
    
    // 直接用
    public void goToWork() {
        vehicle.take(name, home, office);
    }
}
復(fù)制代碼

setter方法注入

另一種方式是使用方法注入,一般是使用要依賴(lài)的對(duì)象對(duì)應(yīng)的屬性的setter方法來(lái)注入。比如:

public class Worker() {
    private String name;
    private String home;
    private String office;
    private Vehicle vehicle;
    
    // 通過(guò)setter方法注入
    public void setVehicle(Vehicle vehicle) {
        this.vehicle = vehicle;
    }
    
    // 直接用
    public void goToWork() {
        vehicle.take(name, home, office);
    }
}
復(fù)制代碼

屬性注入

構(gòu)造器和setter方法都有些麻煩,需要寫(xiě)額外的代碼。要是容器可以通過(guò)反射直接注入進(jìn)來(lái)就好了,這樣代碼看起來(lái)比較干凈。比如:

public class Worker() {
    private String name;
    private String home;
    private String office;
    // 容器直接通過(guò)反射把相應(yīng)的對(duì)象注入進(jìn)來(lái)
    private Vehicle vehicle;
    
    // 直接用
    public void goToWork() {
        vehicle.take(name, home, office);
    }
}
復(fù)制代碼

控制反轉(zhuǎn)容器

前面反復(fù)提到的一個(gè)詞,叫“第三方容器”,其實(shí)就是IoC容器。所謂IoC容器,就是可以生產(chǎn)和管理要依賴(lài)的對(duì)象,然后通過(guò)合適的時(shí)機(jī)注入進(jìn)來(lái)。

IoC容器并不等于Spring。還有其它IoC容器框架,比如google開(kāi)發(fā)的Guice等,甚至我們可以自己開(kāi)發(fā)一個(gè)輕量級(jí)的IoC容器。其實(shí)IoC容器實(shí)現(xiàn)起來(lái)并不難。

只是我們平常用Spring比較多,它又提供了非常好用的IoC功能,所以大多數(shù)項(xiàng)目,我們都是用Spring的IoC了。Spring作為IoC容器還是非常成熟和穩(wěn)定的。

依賴(lài)注入和控制反轉(zhuǎn)是什么關(guān)系?

2004年,Martin Fowler探討了同一個(gè)問(wèn)題,既然IOC是控制反轉(zhuǎn),那么到底是“哪些方面的控制被反轉(zhuǎn)了呢?”,經(jīng)過(guò)詳細(xì)地分析和論證后,他得出了答案:“獲得依賴(lài)對(duì)象的過(guò)程被反轉(zhuǎn)了”。控制被反轉(zhuǎn)之后,獲得依賴(lài)對(duì)象的過(guò)程由自身管理變?yōu)榱擞蒊OC容器主動(dòng)注入。于是,他給“控制反轉(zhuǎn)”取了一個(gè)更合適的名字叫做“依賴(lài)注入(Dependency Injection)”。他的這個(gè)答案,實(shí)際上給出了實(shí)現(xiàn)IOC的方法:注入。所謂依賴(lài)注入,就是由IOC容器在運(yùn)行期間,動(dòng)態(tài)地將某種依賴(lài)關(guān)系注入到對(duì)象之中。

所以,依賴(lài)注入(DI)和控制反轉(zhuǎn)(IOC)是從不同的角度的描述的同一件事情,就是指通過(guò)引入IOC容器,利用依賴(lài)關(guān)系注入的方式,實(shí)現(xiàn)對(duì)象之間的解耦。控制反轉(zhuǎn)是解決問(wèn)題的一種思路和方法論,依賴(lài)注入是它的具體實(shí)現(xiàn)方式

在Spring中使用IoC

首先要明確Bean的概念,Spring把需要納入IoC容器觀察的對(duì)象稱(chēng)為Bean。

一些對(duì)象是不用交給Spring管理的,比如POJO對(duì)象,類(lèi)似DO、DTO等對(duì)象(包括DDD中的領(lǐng)域模型),它們都是可以在程序里面通過(guò)new或者builder來(lái)創(chuàng)建的,因?yàn)閯?chuàng)建的時(shí)候要給它們的一些屬性賦值,而且在使用這些類(lèi)時(shí),沒(méi)法使用“依賴(lài)倒置原則”。

聲明Bean

首先第一步要聲明Bean,這樣Bean才能被Spring的IoC容器管理。聲明Bean有很多種方式,在一開(kāi)始,Spring是使用XML的方式來(lái)聲明一個(gè)Bean:

<bean id="myVehicle" class="test.spring.bean.Bus" />
<bean id="worker" class="test.spring.bean.Worker">
    <property name="vehicle">
        <ref bean="myVehicle" />
    </property>
</bean>
復(fù)制代碼

這樣以后如果要依賴(lài)的Bean變了,只需要修改XML文件就行了。

后來(lái)由于XML文件難以閱讀和維護(hù),Spring開(kāi)始支持用注解的方式定義Bean。我們?cè)诙x具體實(shí)現(xiàn)類(lèi)的時(shí)候,可以在class上面加上@Component注解,然后配置好Spring的自動(dòng)掃描路徑,這樣Spring就能夠自己去掃描相應(yīng)的類(lèi),納入IoC容器中進(jìn)行管理了。

@Component
public class A {}
復(fù)制代碼

@Component的語(yǔ)義其實(shí)不是很明確,因?yàn)?ldquo;萬(wàn)物皆可為組件”。它其實(shí)是一個(gè)元注解,也就是說(shuō),可以注解其它注解。Spring提供了@Controller、@Service、@Repository、@Aspect等注解來(lái)供特定功能的Bean上面使用。

我們自己也可以聲明一些類(lèi)似的注解,如果我們使用DDD,也可以用@Component聲明一些諸如@ApplicationService、@DomainService之類(lèi)的注解。

SpringBoot默認(rèn)的掃描路徑是啟動(dòng)類(lèi)當(dāng)前的包和子包。我們可以通過(guò)@ComponentScan和@ComponentScans來(lái)配置包的掃描路徑。

另一種方式是通過(guò)在方法上聲明@Bean注解來(lái)聲明一個(gè)Bean。這個(gè)時(shí)候一般是會(huì)與@Configuration一起來(lái)配合使用的。

@Configuration
public class MyConfig {
    @Bean
    public B getB() {
        return new B();
    }
}
復(fù)制代碼

一般只有在對(duì)框架提供的Bean有一些特殊配置的時(shí)候,才會(huì)使用@Bean注解。比如數(shù)據(jù)庫(kù)配置等。

使用Bean

使用Bean也有很多種方式。XML就不說(shuō)了,上面例子也展示了如何在XML里配置Bean的注入。

Spring比較推薦的是使用構(gòu)造器注入,因?yàn)闃?gòu)造器注入能夠在啟動(dòng)的時(shí)候就檢查要依賴(lài)的對(duì)象是否存在,如果不存在,會(huì)啟動(dòng)失敗并且拋出以下異常:

Parameter 0 of constructor in com.example.springbase.bean.A required a bean of type 'com.example.springbase.config.B' that could not be found.

The following candidates were found but could not be injected:
    - User-defined bean method 'getB' in 'MyConfig' ignored as the bean value is null


Action:

Consider revisiting the entries above or defining a bean of type 'com.example.springbase.config.B' in your configuration.
復(fù)制代碼

這樣我們就可以更早地發(fā)現(xiàn)依賴(lài)問(wèn)題,而不用在運(yùn)行時(shí)才發(fā)現(xiàn)要依賴(lài)的對(duì)象沒(méi)有被注入進(jìn)來(lái),發(fā)生一些空指針異常。

另一種方式是注解注入,注解注入的好處是代碼簡(jiǎn)潔,不用專(zhuān)門(mén)寫(xiě)構(gòu)造器。Spring支持三個(gè)注解:

  • Resource - JSR250定義
  • Inject - JSR330定義
  • Autowired - Spring提供

其中@Resource和@Inject都是在JSR中定義的規(guī)范,主流的IoC框架都已經(jīng)支持了這兩個(gè)規(guī)范。這兩個(gè)規(guī)范的區(qū)別在于,查找Bean的方式不同。

@Resource是先通過(guò)名稱(chēng)匹配,找不到再通過(guò)類(lèi)型匹配,找不到再通過(guò)結(jié)合@Qualifier來(lái)匹配。

而@Inject是先通過(guò)類(lèi)型匹配,找不到再通過(guò)Qualifier來(lái)匹配,找不到再通過(guò)名稱(chēng)匹配。如果要使用@Inject,需要引入額外的包:

<dependency>  
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency> 
復(fù)制代碼

@Autowired和@Inject的用法一致,唯一區(qū)別就是@Autowired屬于Spring框架提供的注解。

其實(shí)最推薦的是使用JSR-330的規(guī)范,這樣可以做到與框架無(wú)關(guān)。但是筆者發(fā)現(xiàn)大多數(shù)項(xiàng)目還是使用@Autowired居多,而且很難真正做到與Spring框架無(wú)關(guān),因?yàn)锧Component就是Spring提供的注解。我們平時(shí)經(jīng)常使用的@Controller、@Service、@Repository、@Aspect等注解也都是Spring提供的。

所以如果要說(shuō)推薦一個(gè)注解的話(huà),筆者更推薦Spring的@Autowired。

還有一種方式,可以從Spring的上下文中直接拿Bean。這種方式一般用于:從一個(gè)不受Spring管理的對(duì)象中獲取一個(gè)Bean。比如說(shuō)二方包里面的代碼,就有可能會(huì)有這種情況。

// 定義一個(gè)aware,持有一個(gè)static的context對(duì)象
@Component
public class MySpringContextAware implements ApplicationContextAware {

    public static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        MySpringContextAware.applicationContext = applicationContext;
    }
}

// A是不受Spring管理的
public class A {
    // B是受Spring管理的
    private B b;

    public A() {
        System.out.println("a init");
        // 這樣就可以在不受Spring管理的對(duì)象里面,獲取到Bean了
        this.b = (B) MySpringContextAware.applicationContext.getBean(B.class);;
        System.out.println(b.hashCode());
    }
}
復(fù)制代碼

常見(jiàn)問(wèn)題

單例和多例

Spring默認(rèn)Bean是單例的。因?yàn)榻^大多數(shù)Bean其實(shí)是“無(wú)狀態(tài)的”,比如Controller、Service、Repository。所以多個(gè)線(xiàn)程去使用同一個(gè)Bean不會(huì)造成什么問(wèn)題。本著節(jié)約成本的理念,使用單例Bean比較好。

但是有時(shí)候我們可能會(huì)需要一個(gè)“有狀態(tài)”的類(lèi),它內(nèi)部又依賴(lài)其它Bean。比如一個(gè)Context或者一個(gè)Processor之類(lèi)的。對(duì)于這種有狀態(tài)有依賴(lài)其它Bean的類(lèi),有兩種設(shè)計(jì)思路:

  • 不給Spring管理,如果要用到其它Bean,使用上面的applicationContext來(lái)直接獲取Bean。
  • 給Spring管理,做成多例Bean,每次都新建一個(gè)

第二種使用起來(lái)會(huì)更優(yōu)雅一些,也比較好測(cè)試一點(diǎn)。這里有一個(gè)小問(wèn)題,我們來(lái)考慮以下這種情況:如果我們使用了一個(gè)多例Bean,它可能會(huì)依賴(lài)一些單例Bean,這個(gè)很好解決,在多例Bean中正常地注入單例Bean就行了。但是,如果我們要在一個(gè)單例Bean中使用一個(gè)多例Bean,我們知道無(wú)論是構(gòu)造器注入,還是方法注入,還是屬性注入,都只會(huì)在Bean初始化的時(shí)候注入一次,那怎么能保證多個(gè)線(xiàn)程得到的是不同的多例Bean呢?

所以要在單例Bean中使用多例Bean,不能使用一般的自動(dòng)注入。Spring提供了@Lookup注解來(lái)幫我們做這個(gè)事。它是方法級(jí)別的注解。

// 定義一個(gè)多例Bean
@Component
@Scope("prototype")
public class PrototypeBean {
    public void say() {
        System.out.println("say something...");
    }
}


@Component
public class SingletonBean {
 
    public void print() {
        // 單例Bean中用多例Bean
        PrototypeBean bean = methodInject();
        System.out.println("Bean SingletonBean's HashCode " + bean.hashCode());
    }
 
    @Lookup
    public PrototypeBean methodInject() {
        return null;
    }
}
復(fù)制代碼

需要注意的是,用@Lookup修飾的方法,不能是private的。可以是包訪(fǎng)問(wèn)權(quán)限、protected或public的。這里推薦寫(xiě)成public的,這樣在單元測(cè)試的時(shí)候比較方便mock。

循環(huán)依賴(lài)

循環(huán)依賴(lài)其實(shí)很好理解,就是A依賴(lài)B,而B(niǎo)又依賴(lài)A。這樣就形成了循環(huán)依賴(lài)。那Spring是如何解決循環(huán)依賴(lài)的呢?

聰明你的肯定能夠馬上想到,如果兩個(gè)Bean都是使用構(gòu)造器注入,那是不能解決循環(huán)依賴(lài)的,一旦有循環(huán)依賴(lài)只能報(bào)錯(cuò)。而如果是屬性注入或者方法注入,那可以先初始化兩個(gè)Bean,然后分別延遲注入進(jìn)去。這樣就可以解決循環(huán)依賴(lài)的問(wèn)題。

這也是為什么我們推薦使用構(gòu)造器注入。循環(huán)依賴(lài)不是一個(gè)好設(shè)計(jì),構(gòu)造器注入可以提早發(fā)現(xiàn)這種循環(huán)依賴(lài)。

Spring使用了一個(gè)叫做三級(jí)緩存的東西來(lái)解決循環(huán)依賴(lài),具體的實(shí)現(xiàn)細(xì)節(jié)本文不做討論,感興趣的讀者可以自己去找找相關(guān)的文章。

給不給Spring管理?

又回到上面那個(gè)單例和多例的問(wèn)題。如果一個(gè)類(lèi)是多例的,那它一般是有狀態(tài)的,我們有必要把它交給Spring管理嗎?或者說(shuō),有必要交給IoC容器管理嗎?

在回答這個(gè)問(wèn)題之前,我們先假設(shè)一下,如果不給IoC容器管理,會(huì)怎樣?我們從三個(gè)角度來(lái)考慮:

  • 這個(gè)類(lèi)依不依賴(lài)其它Bean
  • 這個(gè)類(lèi)是不是單例的

如果這個(gè)類(lèi)不依賴(lài)其它Bean,那其實(shí)不太需要交給IoC容器管理,POJO類(lèi)就是一個(gè)很典型的例子。但如果這個(gè)類(lèi)是一個(gè)單例的,那其實(shí)推薦交給IoC容器管理,因?yàn)橐约罕WC單例是比較麻煩的,而且不優(yōu)雅。不信去看看單例模式的各種實(shí)現(xiàn)。

如果這個(gè)類(lèi)依賴(lài)其它Bean,那推薦交給IoC容器管理,不然還得使用上面的那種applicationContext的getBean方法來(lái)獲取依賴(lài)的Bean,這就與IoC框架耦合了,不太劃算。

關(guān)于作者

我是Yasin,一個(gè)有顏有料又有趣的程序員。

微信公眾號(hào):編了個(gè)程

個(gè)人網(wǎng)站:yasinshaw.com

分享到:
標(biāo)簽:Spring IoC
用戶(hù)無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定