最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring中的注入list集合

 更新時(shí)間:2022年11月21日 08:47:13   作者:小小少年_  
這篇文章主要介紹了spring中的注入list集合問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

spring在幫我們管理bean的時(shí)候,會幫我們完成自動注入,其中有一個(gè)比較特殊的類型:list

這篇筆記主要記錄spring注入list集合的原理

spring注入list集合

應(yīng)用

public interface Rest {

}

@Component
public class RestServiceImpl01 implements Rest{

}

@Component
public class RestServiceImpl02 implements Rest{

}

@Component
public class OrderService {
? ? @Autowired
? ? //@Qualifier
? ? private List<Rest> restList;

? ? public void test() {
? ? ? ? System.out.println("打印注入的集合的值,restList:" + restList);
? ? }
}

public class Test {

? ? public static void main(String[] args) {
? ? ? ? AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
? ? ? ? OrderService orderService = ac.getBean(OrderService.class);
? ? ? ? orderService.test();
? ? }
}

以上代碼執(zhí)行之后,打印的結(jié)果是:

打印注入的集合的值,restList:[com.spring.list.RestServiceImpl01@60611244, com.spring.list.RestServiceImpl02@3745e5c6]

spring中,在使用@Autowired注解注入list集合的時(shí)候,并不會根據(jù)List類型去容器中查找,而是根據(jù)list集合的元素類型,從spring容器中找到所有的實(shí)現(xiàn)類,放在list集合中,然后注入到bean中

那如果我們想要指定只注入部分bean怎么辦呢?

@Component
public class OrderService {
? ? @Autowired
? ? @Qualifier
? ? private List<Rest> restList;

? ? public void test() {
? ? ? ? System.out.println("打印注入的集合的值,restList:" + restList);
? ? }
}

只需要把這的@Qualifier注解放開,然后在需要注入的bean上,加上這個(gè)注解

@Component
@Qualifier
public class RestServiceImpl02 implements Rest{

}

此時(shí)再運(yùn)行代碼:打印注入的集合的值,restList:[com.spring.list.RestServiceImpl02@d706f19]

所以這就是注入list集合bean的應(yīng)用

原理

對于bean的注入,如果我們使用的是@Autowired注解,會被AutowiredAnnotationBeanPostProcessor處理

鏈路:

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
            org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#resolveFieldValue
    org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency
        org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency

在doResolveDependency方法中,有一個(gè)代碼邏輯

Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
?? ?return multipleBeans;
}

這里就是來解析list類型的

org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveMultipleBeans
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
?? ?Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
?? ?if (elementType == null) {
?? ??? ?return null;
?? ?}
?? ?// 在這里會取解析list集合中指定的接口所有的實(shí)現(xiàn)類
?? ?Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
?? ??? ??? ?new MultiElementDescriptor(descriptor));
?? ?if (matchingBeans.isEmpty()) {
?? ??? ?return null;
?? ?}
?? ?if (autowiredBeanNames != null) {
?? ??? ?autowiredBeanNames.addAll(matchingBeans.keySet());
?? ?}
?? ?TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
?? ?Object result = converter.convertIfNecessary(matchingBeans.values(), type);
?? ?if (getDependencyComparator() != null && result instanceof List) {
?? ??? ?((List<?>) result).sort(adaptDependencyComparator(matchingBeans));
?? ?}
?? ?return result;
}

在這個(gè)方法中,這段代碼是來解析list集合的,所以只截取了這一部分代碼,這一部分關(guān)鍵的代碼是:findAutowireCandidates方法

protected Map<String, Object> findAutowireCandidates(
?? ??? ?@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {

?? ?/**
?? ? * 根據(jù)類型,獲取當(dāng)前beanDefinitionMap中的beanName,注意:這里是從beanDefinitionMap中獲取的,并不是直接從spring
?? ? * 容器中獲取
?? ? * 獲取到的是待注入bean的name
?? ? */
?? ?String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
?? ??? ??? ?this, requiredType, true, descriptor.isEager());
?? ?Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
?? ?/**
?? ? * resolvableDependencies:這里來遍歷這個(gè)集合,判斷要注入的bean是否是該類型的
?? ? * resolvableDependencies這個(gè)集合,默認(rèn)有四個(gè)值
?? ? * interface org.springframework.context.ApplicationContext" -> {AnnotationConfigApplicationContext@1641}
?? ? * interface org.springframework.beans.factory.BeanFactory" -> {DefaultListableBeanFactory@1630}
?? ? * interface org.springframework.core.io.ResourceLoader" -> {AnnotationConfigApplicationContext@1641}?
?? ? * interface org.springframework.context.ApplicationEventPublisher -> {AnnotationConfigApplicationContext@1641}
?? ? */
?? ?for (Class<?> autowiringType : this.resolvableDependencies.keySet()) {
?? ??? ?if (autowiringType.isAssignableFrom(requiredType)) {
?? ??? ??? ?Object autowiringValue = this.resolvableDependencies.get(autowiringType);
?? ??? ??? ?autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
?? ??? ??? ?if (requiredType.isInstance(autowiringValue)) {
?? ??? ??? ??? ?result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
?? ??? ??? ??? ?break;
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?/**
?? ? * 確切的說,是在isAutowireCandidate里面對Qualifier注解進(jìn)行了判斷
?? ? * ?org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate(org.springframework.beans.factory.config.BeanDefinitionHolder, org.springframework.beans.factory.config.DependencyDescriptor)
?? ? */
?? ?for (String candidate : candidateNames) {
?? ??? ?if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
?? ??? ??? ?addCandidateEntry(result, candidate, descriptor, requiredType);
?? ??? ?}
?? ?}
?? ?if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) {
?? ??? ?// Consider fallback matches if the first pass failed to find anything...
?? ??? ?DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
?? ??? ?for (String candidate : candidateNames) {
?? ??? ??? ?if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) {
?? ??? ??? ??? ?addCandidateEntry(result, candidate, descriptor, requiredType);
?? ??? ??? ?}
?? ??? ?}
?? ??? ?if (result.isEmpty()) {
?? ??? ??? ?// Consider self references as a final pass...
?? ??? ??? ?// but in the case of a dependency collection, not the very same bean itself.
?? ??? ??? ?for (String candidate : candidateNames) {
?? ??? ??? ??? ?if (isSelfReference(beanName, candidate) &&
?? ??? ??? ??? ??? ??? ?(!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
?? ??? ??? ??? ??? ??? ?isAutowireCandidate(candidate, fallbackDescriptor)) {
?? ??? ??? ??? ??? ?addCandidateEntry(result, candidate, descriptor, requiredType);
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?return result;
}

在源碼中,就是在isAutowireCandidate()這個(gè)方法中,對@Qualifier注解進(jìn)行的過濾,也就是說,如果我們在注入list集合的時(shí)候,沒有添加@Qualifier注解,那這個(gè)方法都會返回true,然后將所有的實(shí)現(xiàn)類都返回如果加了@Qualifier注解,這里只有加了@Qualifier注解的實(shí)現(xiàn)類會返回TRUE,會被返回

這個(gè)方法的實(shí)現(xiàn)細(xì)節(jié),待研究,debug看源碼的時(shí)候,看到這樣的結(jié)果

小結(jié)

所以,在spring中,我們在注入list集合的時(shí)候,如果只加了@Autowired注解,那就會把集合元素的所有實(shí)現(xiàn)類都注入進(jìn)來,如果想只注入指定的類,那就使用@Qualifier注解

spring集合注入的幾種方式

什么是集合注入

通俗的來講就是在beans.xml文件中,通過集合的方式來進(jìn)行賦值,我們在Java基礎(chǔ)中學(xué)過通過集合的方式來進(jìn)行賦值

集合注入的幾種方式

Spring提供了以下四種集合類的配置元素

1、list 該標(biāo)簽用來裝配可重復(fù)的list值

2、set 該標(biāo)簽用來裝配沒有重復(fù)的set值

3、map 該標(biāo)簽可用來注入鍵和值可以為任何類型的鍵值對

4、props 該標(biāo)簽支持注入鍵和值都是字符串類型的鍵值對

簡單的配置代碼實(shí)現(xiàn)

1、Programmer類的創(chuàng)建

package com.model;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class Programmer {
    private List<String> cars;
    private Set<String> pats; //寵物
    private Map<String,String> infos; //信息
    private Properties mysqlInfos; //mysql數(shù)據(jù)庫鏈接信息
    private String[] numbers; //家庭成員

    public List<String> getCars() {
        return cars;
    }

    public void setCars(List<String> cars) {
        this.cars = cars;
    }

    public Set<String> getPats() {
        return pats;
    }

    public void setPats(Set<String> pats) {
        this.pats = pats;
    }

    public Map<String, String> getInfos() {
        return infos;
    }

    public void setInfos(Map<String, String> infos) {
        this.infos = infos;
    }

    public Properties getMysqlInfos() {
        return mysqlInfos;
    }

    public void setMysqlInfos(Properties mysqlInfos) {
        this.mysqlInfos = mysqlInfos;
    }

    public String[] getNumbers() {
        return numbers;
    }

    public void setNumbers(String[] numbers) {
        this.numbers = numbers;
    }
}

2、beans.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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--
    集合注入
    -->
    <bean id="programmer" class="com.model.Programmer">
        <property name="cars">
            <!-- 1.  list數(shù)據(jù)注入 //有序集合-->
            <list>
                <value>ofo</value>
                <value>mobai</value>
                <value>寶馬</value>
            </list>
        </property>

        <property name="pats">
            <!-- 2. set數(shù)據(jù)注入 //無序集合-->
            <set>
                <value>小黑</value>
                <value>小紅</value>
                <value>小白</value>
            </set>
        </property>

        <property name="infos">
            <!-- 3. map數(shù)據(jù)注入 -->
            <map>
                <entry key="name" value="cjx"></entry>
                <entry key="age" value="23"></entry>
                <entry key="id" value="20821111355"></entry>
            </map>
        </property>

        <property name="mysqlInfos">
            <!-- 4. properties數(shù)據(jù)注入  //實(shí)際也是set類型是無序的-->
            <props>
                <prop key="url">mysql:jdbc://localhost:3306/dbname</prop>
                <prop key="user">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>

        <property name="numbers">
            <!-- 5. 數(shù)組的數(shù)據(jù)注入 -->
            <array>
                <value>哥哥</value>
                <value>弟弟</value>
                <value>妹妹</value>
                <value>姐姐</value>
            </array>
        </property>
    </bean>
</beans>

3、創(chuàng)建Lesson測試

public class Lesson4 {

    @Test
    public void test() throws Exception{

        /*
        * bean的集合注入
        * */
        ApplicationContext context = new ClassPathXmlApplicationContext("beans4.xml");
        Programmer programmer = (Programmer) context.getBean("programmer");
       
       
	 	System.out.println("車:"+programmer.getCars());
        System.out.println("寵物:"+programmer.getPats());
        System.out.println("信息:"+programmer.getInfos());
        System.out.println("數(shù)據(jù)庫連接信息::"+programmer.getMysqlInfos());
        System.out.println("家庭成員:");
        //家庭成員是數(shù)組類型,需要遍歷
        for (String number: programmer.getNumbers()){
            System.out.println(number);
        }
    }
}

4、測試運(yùn)行結(jié)果

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • idea +junit單元測試獲取不到bean注入的解決方式

    idea +junit單元測試獲取不到bean注入的解決方式

    這篇文章主要介紹了idea +junit單元測試獲取不到bean注入的解決方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • 圖解Java經(jīng)典算法歸并排序的原理與實(shí)現(xiàn)

    圖解Java經(jīng)典算法歸并排序的原理與實(shí)現(xiàn)

    歸并排序是建立在歸并操作上的一種有效的排序算法。該算法是采用分治法(Divide?and?Conquer)的一個(gè)非常典型的應(yīng)用。本文將通過動圖詳解歸并排序的原理及實(shí)現(xiàn),需要的可以參考一下
    2022-09-09
  • Java由淺入深分析多態(tài)的概念

    Java由淺入深分析多態(tài)的概念

    多態(tài)就是指程序中定義的引用變量所指向的具體類型和通過該引用變量發(fā)出的方法調(diào)用在編程時(shí)并不確定,而是在程序運(yùn)行期間才確定,即一個(gè)引用變量到底會指向哪個(gè)類的實(shí)例對象,該引用變量發(fā)出的方法調(diào)用到底是哪個(gè)類中實(shí)現(xiàn)的方法,必須在由程序運(yùn)行期間才能決定
    2022-04-04
  • 解決@PathVariable出現(xiàn)點(diǎn)號.時(shí)導(dǎo)致路徑參數(shù)截?cái)喃@取不全的問題

    解決@PathVariable出現(xiàn)點(diǎn)號.時(shí)導(dǎo)致路徑參數(shù)截?cái)喃@取不全的問題

    這篇文章主要介紹了解決@PathVariable出現(xiàn)點(diǎn)號.時(shí)導(dǎo)致路徑參數(shù)截?cái)喃@取不全的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Springboot整合Swagger2和Swagger3全過程

    Springboot整合Swagger2和Swagger3全過程

    這篇文章主要介紹了Springboot整合Swagger2和Swagger3全過程,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java 小游戲開發(fā)之俄羅斯方塊

    Java 小游戲開發(fā)之俄羅斯方塊

    這篇文章主要介紹了Java 小游戲開發(fā)之俄羅斯方塊的相關(guān)資料,這里實(shí)現(xiàn)俄羅斯方塊的實(shí)例和實(shí)現(xiàn)效果給大家看下,學(xué)習(xí)java基礎(chǔ)的朋友的好資料,需要的朋友可以參考下
    2017-07-07
  • mybatis-plus開啟sql日志打印的三種方法

    mybatis-plus開啟sql日志打印的三種方法

    本文主要介紹了mybatis-plus開啟sql日志打印的三種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 使用JSONObject.toJSONString 過濾掉值為空的key

    使用JSONObject.toJSONString 過濾掉值為空的key

    這篇文章主要介紹了使用JSONObject.toJSONString 過濾掉值為空的key,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 一文解開java中字符串編碼的小秘密(干貨)

    一文解開java中字符串編碼的小秘密(干貨)

    這篇文章主要介紹了一文解開java中字符串編碼的小秘密(干貨),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 一次 Java 服務(wù)性能優(yōu)化實(shí)例詳解

    一次 Java 服務(wù)性能優(yōu)化實(shí)例詳解

    這篇文章主要介紹了一次 Java 服務(wù)性能優(yōu)化實(shí)例詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07

最新評論

建水县| 江都市| 滦南县| 阳原县| 隆化县| 育儿| 德江县| 永川市| 大荔县| 香格里拉县| 漳平市| 勃利县| 南开区| 葵青区| 广东省| 隆化县| 镇康县| 阿拉善右旗| 丰都县| 赤壁市| 手游| 胶州市| 安吉县| 黔西县| 翁牛特旗| 泽库县| 黄大仙区| 罗源县| 青铜峡市| 本溪市| 东阳市| 洪湖市| 铜川市| 边坝县| 临洮县| 西乌| 山东省| 太康县| 三门峡市| 永福县| 旌德县|