中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

Spring容器怎么配置

這篇文章主要講解了“Spring容器怎么配置”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Spring容器怎么配置”吧!

創(chuàng)新互聯(lián)建站服務(wù)項(xiàng)目包括新賓網(wǎng)站建設(shè)、新賓網(wǎng)站制作、新賓網(wǎng)頁(yè)制作以及新賓網(wǎng)絡(luò)營(yíng)銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,新賓網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到新賓省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

1.容器概覽

Spring 中的 Ioc 容器,我們可以大致上分為兩種:

  • BeanFactory
  • ApplicationContext
 

1.1 BeanFactory

BeanFactory 是最最基礎(chǔ)的 IoC 容器,它提供了一個(gè) IoC 容器所需的基本功能。在本系列前面文章中我們所用到的 XmlBeanFactory 就是它的實(shí)現(xiàn)之一。

BeanFactory 默認(rèn)采用延遲初始化策略,即當(dāng)容器啟動(dòng)時(shí),并未完成 Bean 的初始化,只有當(dāng)調(diào)用到該 Bean 的實(shí)例時(shí),才會(huì)完成其初始化操作,并進(jìn)行依賴注入。

例如如下代碼:

XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
User user = factory.getBean(User.class);
 

當(dāng)?shù)谝恍写a執(zhí)行的時(shí)候,beans.xml 中配置的 User 對(duì)象并未進(jìn)行初始化,只有當(dāng)?shù)诙?getBean 方法調(diào)用時(shí),User 對(duì)象才進(jìn)行了初始化操作。

這樣設(shè)計(jì)的好處是容器啟動(dòng)速度快,因?yàn)橐龅氖虑楸容^少。

 

1.2 ApplicationContext

ApplicationContext 是在 BeanFactory 的基礎(chǔ)上實(shí)現(xiàn)的,BeanFactory 的功能它都有,算是一種高級(jí)容器。

ApplicationContext 在 BeanFactory 的基礎(chǔ)上提供了事件發(fā)布、國(guó)際化等功能。

同時(shí),ApplicationContext 和 BeanFactory 還有一個(gè)很大的不同在于 ApplicationContext 在容器啟動(dòng)時(shí),就會(huì)完成所有 Bean 的初始化,這也就以為著容器啟動(dòng)時(shí)間較長(zhǎng),并且對(duì)系統(tǒng)資源要求也較高。

例如如下一段代碼:

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
 

當(dāng)這段代碼執(zhí)行時(shí),beans.xml 中配置的 User 對(duì)象就會(huì)完成初始化操作。

 

2.BeanFactory

BeanFactory 的繼承關(guān)系圖太大了,放在文章里顯示不全。小伙伴們可以在 IDEA 中自行查看,我這里就不貼圖出來了。

我們來看下 BeanFactory 的源碼:

public interface BeanFactory {
 String FACTORY_BEAN_PREFIX = "&";
 Object getBean(String name) throws BeansException;
 <T> T getBean(String name, Class<T> requiredType) throws BeansException;
 Object getBean(String name, Object... args) throws BeansException;
 <T> T getBean(Class<T> requiredType) throws BeansException;
 <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
 <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
 <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
 boolean containsBean(String name);
 boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
 boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
 boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
 boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
 @Nullable
 Class<?> getType(String name) throws NoSuchBeanDefinitionException;
 @Nullable
 Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;
 String[] getAliases(String name);
}
 

可以看到,BeanFactory 主要提供了一些和 Bean 相關(guān)的查詢方法。

FACTORY_BEAN_PREFIX

這是定義的 FactoryBean 前綴,具體參考Spring 源碼第 9 篇,深入分析 FactoryBean。

getBean

getBean 方法一共有五個(gè)。

在獲取一個(gè) Bean 的時(shí)候,可以指定 Bean 的名字,也可以指定 Bean 的類型,也可以同時(shí)指定,這個(gè)好理解。

還有兩個(gè)重載的方法里邊有一個(gè) args 參數(shù),這個(gè)可能有的小伙伴們沒怎么用過,我這里稍微解釋下。

其實(shí)我們大概能猜出來 args 是獲取 Bean 時(shí)所需要的參數(shù),如果使用該方法給 Bean 配置參數(shù),需要將 Bean 的 scope 設(shè)置為 prototype,這就意味著每次獲取 Bean 的時(shí)候,才去進(jìn)行 Bean 的初始化(否則配置的參數(shù)無法生效)。

松哥通過一個(gè)例子來給大家演示下。

首先我們提供一個(gè) User 類:

public class User {
    private String username;
    private Integer age;

    public User(String username, Integer age) {
        this.username = username;
        this.age = age;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
}
 

可以看到,User 類只有一個(gè)有參的構(gòu)造方法。

接下來我們?cè)?XML 文件中進(jìn)行配置,XML 文件中需要配置 User 類的構(gòu)造方法參數(shù),我們可以配置為 null,同時(shí)記得設(shè)置 scope 屬性為 prototype。

<bean class="org.javaboy.spring_demo04.User" id="user1" scope="prototype">
    <constructor-arg name="username"><null></null></constructor-arg>
    <constructor-arg name="age"><null></null></constructor-arg>
</bean>
 

最后再通過如下方式加載 Bean:

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
User user = ctx.getBean(User.class,new Object[]{"javaboy",99});
System.out.println("user = " + user);
 

最終打印結(jié)果如下:

user = User{username='javaboy', age=99}
 

可以看到,為 Bean 配置的參數(shù)都生效了。

getBeanProvider

方法用于獲取指定 Bean 的提供者,可以看到它返回的是一個(gè) ObjectProvider,該類擴(kuò)展自 ObjectFactory,從 Spring4.3 時(shí)開始提供。

可能大家對(duì) ObjectProvider 接觸較少,這里我也稍微說一下。

先來看 ObjectFactory:

@FunctionalInterface
public interface ObjectFactory<T> {
 T getObject() throws BeansException;
}
 

ObjectFactory 有點(diǎn)類似于我們?cè)?Spring 源碼第 9 篇,深入分析 FactoryBean 一文中所講的 FactoryBean。

不同的是,ObjectFactory 中只有一個(gè) getObject 方法,該方法可以返回 Object 實(shí)例。ObjectFactory 與 FactoryBean 相似,但是后者的實(shí)現(xiàn)通常是在 BeanFactory 中定義為 SPI 實(shí)例,而此類的實(shí)現(xiàn)通常是作為 API 注入給其他 Bean。

再來看 ObjectProvider(部分):

public interface ObjectProvider<T> extends ObjectFactory<T>, Iterable<T> {
    //返回指定類型的 bean, 如果容器中不存在, 拋出 NoSuchBeanDefinitionException 異常;如果容器中有多個(gè)此類型的 bean, 拋出 NoUniqueBeanDefinitionException 異常
 T getObject(Object... args) throws BeansException;
    //如果指定類型的 bean 注冊(cè)到容器中, 返回 bean 實(shí)例, 否則返回 null
 @Nullable
 T getIfAvailable() throws BeansException;
    //如果指定類型的 bean 在容器中只有一個(gè) bean, 返回 bean 實(shí)例, 如果不存在則返回 null;如果容器中有多個(gè)此類型的 bean, 拋出 NoUniqueBeanDefinitionException 異常
 @Nullable
 T getIfUnique() throws BeansException;
    // Spring5.0 之后提供,返回指定類型 Bean 的迭代器
 @Override
 default Iterator<T> iterator() {
  return stream().iterator();
 }
    //轉(zhuǎn)為 Stream
 default Stream<T> stream() {
  throw new UnsupportedOperationException("Multi element access not supported");
 }
 default Stream<T> orderedStream() {
  throw new UnsupportedOperationException("Ordered element access not supported");
 }
}
 

這是 ObjectProvider 的源碼,那么它有什么用呢?松哥舉個(gè)簡(jiǎn)單例子。

在 Spring4.3 之前。

假設(shè)我有一個(gè) UserDao,如下:

@Repository
public class UserDao {
}
 

還有一個(gè) UserService,如下:

@Service
public class UserService {
    private UserDao userDao;

    @Autowired
    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public String toString() {
        return "UserService{" +
                "userDao=" + userDao +
                '}';
    }
}
 

在 UserService 中注入 UserDao 時(shí),必須明確給出 @Autowired 注解。

這看起來不夠優(yōu)雅!

從 Spring4.3 開始,在 UserService 中注入 UserDao 時(shí),如果構(gòu)造方法只有一個(gè)參數(shù),可以不用添加 @Autowired 注解,像下面這樣:

@Service
public class UserService {
    private UserDao userDao;

    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public String toString() {
        return "UserService{" +
                "userDao=" + userDao +
                '}';
    }
}
 

但是如果 UserDao 為 null,則會(huì)導(dǎo)致 UserService 初始化失敗,通過 ObjectProvider 可以解決,如下:

@Service
public class UserService {
    private UserDao userDao;

    public UserService(ObjectProvider<UserDao> userDao) {
        this.userDao = userDao.getIfUnique();
    }

    @Override
    public String toString() {
        return "UserService{" +
                "userDao=" + userDao +
                '}';
    }
}
 

這就是 ObjectProvider。好啦,扯遠(yuǎn)了,我們回到 BeanFactory 繼續(xù)看它里邊的方法。

containsBean

判斷容器中是否包含某個(gè) Bean。

isSingleton

判斷某個(gè) Bean 是否是單例的。

isPrototype

判斷某個(gè) Bean 是否是 prototype。

isTypeMatch

返回指定名稱的 Bean 是否匹配指定的類型。

getType

返回指定名稱的 Bean 對(duì)應(yīng)的數(shù)據(jù)類型。

getAliases

返回 Bean 的別名。

這就是 BeanFactory 中定義的所有方法,可以看到,基本上都是容器相關(guān)的查詢方法,接下來將在 BeanFactory 的各種實(shí)現(xiàn)類中,對(duì)其進(jìn)行實(shí)現(xiàn)。

 

3.二級(jí)接口

BeanFactory 作為 IoC 容器中最頂層的定義,沒有繼承任何接口,我們可以稱之為一級(jí)接口,直接繼承自 BeanFactory 的接口有三個(gè),我們稱之為二級(jí)接口。

 

3.1 HierarchicalBeanFactory

HierarchicalBeanFactory 繼承自 BeanFactory,定義了工廠分層,在其基礎(chǔ)上又?jǐn)U展了兩個(gè)方法:

public interface HierarchicalBeanFactory extends BeanFactory {
 BeanFactory getParentBeanFactory();
 boolean containsLocalBean(String name);
}
 
  • getParentBeanFactory 方法返回 Bean 工廠的父工廠,實(shí)現(xiàn)了工廠分層。
  • containsLocalBean 方法則判斷本地工廠是否包含這個(gè) Bean。

HierarchicalBeanFactory 有一個(gè)接口 ConfigurableBeanFactory,ConfigurableBeanFactory 接口繼承自 HierarchicalBeanFactory 和 SingletonBeanRegistry,其中 SingletonBeanRegistry 這個(gè)接口定義了對(duì)單例 Bean 的定義以及獲取方法。也就是說,ConfigurableBeanFactory 中兼具工廠分層和單例處理功能。同時(shí),在 HierarchicalBeanFactory 中 getParentBeanFactory 所 get 到的對(duì)象,也是在 ConfigurableBeanFactory 中完成配置。

 

3.2 AutowireCapableBeanFactory

AutowireCapableBeanFactory 繼承自 BeanFacotory,它擴(kuò)展了自動(dòng)裝配的功能。

public interface AutowireCapableBeanFactory extends BeanFactory {
 int AUTOWIRE_NO = 0;
 int AUTOWIRE_BY_NAME = 1;
 int AUTOWIRE_BY_TYPE = 2;
 int AUTOWIRE_CONSTRUCTOR = 3;
 @Deprecated
 int AUTOWIRE_AUTODETECT = 4;
 String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";
 <T> T createBean(Class<T> beanClass) throws BeansException;
 Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
 void autowireBean(Object existingBean) throws BeansException;
 Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
 void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException;
 Object configureBean(Object existingBean, String beanName) throws BeansException;
 Object initializeBean(Object existingBean, String beanName) throws BeansException;
 void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
 Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException;
 Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException;
 void destroyBean(Object existingBean);
 <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
 Object resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;
 @Nullable
 Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
 @Nullable
 Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
   @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
}
 

首先通過五個(gè)常量定義了五種不同的裝配策略,分別是:不自動(dòng)裝配、通過名稱自動(dòng)裝配、通過類型自動(dòng)裝配、通過構(gòu)造方法自動(dòng)裝配,還有一個(gè)過期的常量。

ORIGINAL_INSTANCE_SUFFIX 則是初始化實(shí)例給定名稱時(shí)約定的后綴,該后綴會(huì)添加到類的全路徑后面,例如:com.mypackage.MyClass.ORIGINAL。

createBean 方法用來創(chuàng)建 Bean 實(shí)例;autowire* 方法則用來完成自動(dòng)裝配;configureBean 用來配置 Bean;initializeBean 用來初始化 Bean;applyBeanPropertyValues 將指定 beanBeanDefinition 應(yīng)用到一個(gè)已經(jīng)存在的 Bean 上;applyBeanPostProcessorsBeforeInitialization/applyBeanPostProcessorsAfterInitialization 調(diào)用 Bean 的后置處理器;destroyBean 方法用來銷毀 Bean;resolve* 方法用來解析 Bean。

 

3.3 ListableBeanFactory

ListableBeanFactory 繼承自 BeanFacotory,該接口可以列出工廠可以生產(chǎn)的所有實(shí)例。

public interface ListableBeanFactory extends BeanFactory {
 boolean containsBeanDefinition(String beanName);
 int getBeanDefinitionCount();
 String[] getBeanDefinitionNames();
 String[] getBeanNamesForType(ResolvableType type);
 String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);
 String[] getBeanNamesForType(@Nullable Class<?> type);
 String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
 <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
 <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException;
 String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
 Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
 @Nullable
 <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) throws NoSuchBeanDefinitionException;
}
 
  • containsBeanDefinition:判斷容器是否包含某一個(gè) Bean 的定義。
  • getBeanDefinitionCount:獲取 BeanDefinition 數(shù)量。getBeanDefinitionCount 和 containsBeanDefinition 執(zhí)行效率較低,慎用。
  • getBeanDefinitionNames:獲取所有 Bean 的名字。
  • getBeanNamesForType:返回指定類型的 BeanName。
  • getBeansOfType:返回指定類的名稱和 Bean Map(相同類型的 Bean 可能存在多種實(shí)例)。
  • getBeanNamesForAnnotation:根據(jù)注解獲取指定的 BeanName。
  • getBeansWithAnnotation:根據(jù)注解獲取指定的 BeanName 以及 Bean Map。
  • findAnnotationOnBean:根據(jù)指定 beanName 和注解類型查找指定的 Bean。

ListableBeanFactory 有一個(gè)實(shí)現(xiàn)接口 ConfigurableListableBeanFactory,這是以上所介紹接口的集大成者,ConfigurableListableBeanFactory 繼承自 ListableBeanFactory、AutowireCapableBeanFactory 以及 ConfigurableBeanFactory,可以看到,三個(gè)二級(jí)接口功能集于一身,它包含了 BeanFactory 體系目前的所有方法。這些方法都在 DefaultListableBeanFactory 中進(jìn)行實(shí)現(xiàn),也就是我們前面所講的 Spring 源碼第六彈!松哥和大家聊聊容器的始祖 DefaultListableBeanFactory。

這就是直接繼承自 BeanFactory 的三個(gè)接口。

感謝各位的閱讀,以上就是“Spring容器怎么配置”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)Spring容器怎么配置這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

網(wǎng)站標(biāo)題:Spring容器怎么配置
URL標(biāo)題:http://www.rwnh.cn/article8/gopjop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣、網(wǎng)站內(nèi)鏈、網(wǎng)站導(dǎo)航營(yíng)銷型網(wǎng)站建設(shè)、電子商務(wù)、網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
忻州市| 嘉黎县| 南平市| 长葛市| 鹤岗市| 昔阳县| 景东| 都安| 翁源县| 广南县| 永和县| 巴东县| 滨州市| 苗栗市| 蓬莱市| 班玛县| 新乐市| 邛崃市| 顺平县| 万源市| 上栗县| 孟连| 简阳市| 肇庆市| 华阴市| 鹿邑县| 五台县| 娄底市| 堆龙德庆县| 萝北县| 镇沅| 彭泽县| 双城市| 黄山市| 嘉义县| 勐海县| 调兵山市| 平江县| 龙门县| 万州区| 德安县|