Spring依賴(lài)注入的三種方式小結(jié)
Spring的主要特性包括IOC和DI,其中DI是IOC的基礎(chǔ)。在以前的Spring使用過(guò)程中大部分都是使用XML配置文件顯式配置spring組件,導(dǎo)致大量的XML配置文件以及冗余的XML配置代碼。閱讀《Spring in Action》后總結(jié)Spring的DI功能的三種主要裝配方式以及混合裝配方式
根據(jù)注解自動(dòng)裝配
Spring中有非常豐富的注解,通過(guò)這些注解可以方便地配置Spring容器,使得Spring容器可以自動(dòng)識(shí)別相關(guān)Bean并做自動(dòng)注入裝配。
使用注解
- @Component注解:標(biāo)注一個(gè)類(lèi),標(biāo)識(shí)此類(lèi)為一個(gè)Java Bean。
- @Configuration注解:標(biāo)注一個(gè)類(lèi),標(biāo)識(shí)此類(lèi)為一個(gè)Java配置類(lèi)
- @ComponentScan注解:標(biāo)注一個(gè)類(lèi),用以配置掃描的包名稱(chēng)
示例代碼
這里使用一個(gè)最簡(jiǎn)單的例子來(lái)展示自動(dòng)裝配的配置,代碼結(jié)構(gòu)如圖所示。

ActionConfig類(lèi)用于做全局配置,我們知道,一名騎士一般都會(huì)有一匹馬,所以這里Horse和Knight類(lèi)作為Java Bean被Spring容器創(chuàng)建,并將Horse類(lèi)的一個(gè)bean注入到Knight中。所以在Horse和Knight中必須使用@Component注解進(jìn)行修飾。
Knight代碼:
package entities;
import org.springframework.stereotype.Component;
/**
* Created by Administrator on 2017/8/3 0003.
*/
@Component
public class Knight {
private Horse horse;
Knight(Horse horse){
this.horse = horse;
}
public void ride(){
horse.bark();
}
}
Horse代碼:
package entities;
import org.springframework.stereotype.Component;
/**
* Created by Administrator on 2017/8/3 0003.
*/
@Component
public class Horse {
void bark(){
System.out.println("Horse!!!!");
}
}
ActionConfig代碼:
package config;
import entities.Knight;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* Created by Administrator on 2017/8/3 0003.
*/
@Configuration
@ComponentScan(basePackageClasses = {Knight.class})
public class ActionConfig {
}
這里的ComponentScan注解內(nèi)的屬性用以注明Knight類(lèi)所在的包為掃描的基礎(chǔ)包。凡是這個(gè)基礎(chǔ)包及其子包內(nèi)的標(biāo)注了@Component的類(lèi)都將被視為Java Bean,這些Bean被Spring容器創(chuàng)建和管理。
Java配置類(lèi)裝配
從自動(dòng)裝配的代碼中,可以看出自動(dòng)裝配是非常簡(jiǎn)單方便的。Java配置類(lèi)進(jìn)行裝配的方式是采用對(duì)配置類(lèi)中的方法進(jìn)行注解標(biāo)注,實(shí)現(xiàn)bean的創(chuàng)建和管理。
還是采用以上的例子,現(xiàn)在我們將上面的自動(dòng)裝配改成Java配置類(lèi)進(jìn)行裝配。
首先,刪掉Knight和Horse中的@Component注解,刪掉ActionConfig中的@ComponentScn注解,因?yàn)檫@些注解都是自動(dòng)裝配才需要的。
package entities;
/**
* Created by Administrator on 2017/8/3 0003.
*/
public class Knight {
private Horse horse;
public Knight(Horse horse){
this.horse = horse;
}
public void ride(){
horse.bark();
}
}
package entities;
/**
* Created by Administrator on 2017/8/3 0003.
*/
public class Horse {
void bark(){
System.out.println("Horse!!!!");
}
}
ActionConfig類(lèi):
package config;
import entities.Horse;
import entities.Knight;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Created by Administrator on 2017/8/3 0003.
*/
@Configuration
public class ActionConfig {
@Bean
public Knight getKnight(){
return new Knight(getHorse());
}
@Bean
public Horse getHorse(){
return new Horse();
}
}
通過(guò)@Bean注解對(duì)相關(guān)的方法進(jìn)行修飾,Spring就可以知道調(diào)用這些方法來(lái)構(gòu)建相應(yīng)的bean,并注入到依賴(lài)的對(duì)象中。
XML配置文件裝配
使用XML配置文件來(lái)裝配組件是最為繁瑣的,需要對(duì)各個(gè)bean做一一配置,特別是需要配置構(gòu)造器或者setter的參數(shù)。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
以上是一個(gè)空的XML配置文件,看一下就知道,XML真實(shí)復(fù)雜啊...
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="knight" class="entities.Knight">
<constructor-arg ref="horse"></constructor-arg>
</bean>
<bean id="horse" class="entities.Horse"></bean>
</beans>
通過(guò)配置兩個(gè)bean元素,并且通過(guò)constructor-arg元素來(lái)配置構(gòu)造函數(shù)注入的bean,達(dá)到依賴(lài)注入的目的。
導(dǎo)入和混合配置
有時(shí)候單純的XML配置或者Java配置不滿(mǎn)足我們的需求怎么辦呢?Spring支持混合配置的方式來(lái)管理bean,通過(guò)Java和XML配置的混合,達(dá)到你想要的效果。
Java配置中引用Java配置
在配置類(lèi)中使用@Import注解進(jìn)行引入另一個(gè)Java配置類(lèi)。
package config;
import entities.Horse;
import entities.Knight;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* Created by Administrator on 2017/8/3 0003.
*/
@Configuration
@Import(BeautyConfig.class)
public class ActionConfig {
@Bean
public Knight getKnight(){
return new Knight(getHorse());
}
@Bean(name = "horse")
public Horse getHorse(){
return new Horse();
}
}
BeautyConfig代碼:
package config;
import entities.Beauty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Created by Administrator on 2017/8/3 0003.
*/
@Configuration
public class BeautyConfig {
@Bean
Beauty getBeauty(){
return new Beauty();
}
}
在Main中,只需要通過(guò)ActionConfig就可以獲取到所有的上下文對(duì)象。
package main;
import config.ActionConfig;
import entities.Beauty;
import entities.Knight;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* Created by Administrator on 2017/8/3 0003.
*/
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ActionConfig.class);
Knight knight = context.getBean(Knight.class);
knight.ride();
Beauty beauty = context.getBean(Beauty.class);
beauty.sleep();
}
}
這里簡(jiǎn)單使用Import引入了另一個(gè)配置的Java文件,就實(shí)現(xiàn)了將多個(gè)bean分別配置到多個(gè)Java配置類(lèi)中。
Java配置中引入XML配置
在Java中引入xml配置的基本方法與引入Java代碼配置類(lèi)似,只需要將@Import改為@ImportResource,配上x(chóng)ml的文件地址即可。
@ImportResource("classpath:spring.xml")
以上,就是Java配置spring依賴(lài)注入的方法。
XML配置中引入XML配置
同理,在XML配置中引入XML也需要使用Import,但是在XML中是import標(biāo)簽,通過(guò)使用import標(biāo)簽導(dǎo)入另一個(gè)xml文件。
這里我新建了一個(gè)another.xml的文件,用以作為另一個(gè)配置文件示例。在原有的spring.xml中加入以下代碼:
<import resource="another.xml"></import>
這樣就簡(jiǎn)單導(dǎo)入了anoter.xml配置文件。
XML配置中引入Java配置
乍看之下,在XML中似乎沒(méi)有標(biāo)簽可以導(dǎo)入Java配置類(lèi)的,不過(guò)任何Java配置類(lèi)都是一個(gè)bean,所以可以通過(guò)配置bean標(biāo)簽來(lái)導(dǎo)入Java配置類(lèi)!
<bean class="config.BeautyConfig"></bean>
通過(guò)在XML中配置這個(gè)Java配置類(lèi)的bean,就直接導(dǎo)入了在Java配置類(lèi)中的所有bean,真是神奇!
以下是配置XML的全部代碼:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="another.xml"></import>
<bean class="config.BeautyConfig"></bean>
<bean id="knight" class="entities.Knight">
<constructor-arg ref="horse"></constructor-arg>
</bean>
<bean id="horse" class="entities.Horse"></bean>
</beans>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java final 修飾符知識(shí)點(diǎn)總結(jié)(必看篇)
下面小編就為大家?guī)?lái)一篇Java final 修飾符知識(shí)點(diǎn)總結(jié)(必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09
Java線(xiàn)程基本使用之如何實(shí)現(xiàn)Runnable接口
這篇文章主要介紹了Java線(xiàn)程基本使用之如何實(shí)現(xiàn)Runnable接口問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
SpringBoot Actuator監(jiān)控的項(xiàng)目實(shí)踐
本文主要結(jié)合 Spring Boot Actuator,跟大家一起分享微服務(wù)Spring Boot Actuator 的常見(jiàn)用法,方便我們?cè)谌粘V袑?duì)我們的微服務(wù)進(jìn)行監(jiān)控治理,感興趣的可以了解一下2024-01-01
關(guān)于springboot 配置date字段返回時(shí)間戳的問(wèn)題
這篇文章主要介紹了springboot 配置date字段返回時(shí)間戳的問(wèn)題,在springboot2.0后,spring會(huì)將Date字段自動(dòng)給轉(zhuǎn)成UTC字符串了(在沒(méi)有配置的情況下),所以date需要轉(zhuǎn)換成時(shí)間戳還是yyyy-MM-dd HH:mm:ss,具體解決方法跟隨小編一起看看吧2021-07-07
Java中實(shí)現(xiàn)在一個(gè)方法中調(diào)用另一個(gè)方法
下面小編就為大家分享一篇Java中實(shí)現(xiàn)在一個(gè)方法中調(diào)用另一個(gè)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
IntellJ idea使用FileWatch實(shí)時(shí)編譯less文件的方法
這篇文章主要介紹了IntellJ idea使用FileWatch實(shí)時(shí)編譯less文件的相關(guān)資料,需要的朋友可以參考下2018-02-02
JAVA JNI函數(shù)的注冊(cè)過(guò)程詳細(xì)介紹
這篇文章主要介紹了JAVA JNI函數(shù)的注冊(cè)過(guò)程詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2016-11-11

