Spring源码解析-IOC容器的实现-ApplicationContext
上面我们已经知道了IOC的建立的基本步骤了,我们就可以用编码的方式和IOC容器进行建立过程了。其实Spring已经为我们提供了很多实现,想必上面的简单扩展,如XMLBeanFacroty等。我们一般是用ApplicationContext这个接口,这个接口实现了基本的功能外,还添加了很多相应的功能,根据看下面的源码我来看看是怎么实现更多的功能的。
public interface ApplicationContext extends ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
/**
* 返回一个唯一的bean的ID
*/
String getId();
/**
* 返回一个name为context
*/
String getDisplayName();
/**
* 返回第一次加载的时间戳
*/
long getStartupDate();
/**
* Return the parent context, or <code>null</code> if there is no parent
* and this is the root of the context hierarchy.
* @return the parent context, or <code>null</code> if there is no parent
*/
ApplicationContext getParent();
/**
* Expose AutowireCapableBeanFactory functionality for this context.
* <p>This is not typically used by application code, except for the purpose
* of initializing bean instances that live outside the application context,
* applying the Spring bean lifecycle (fully or partly) to them.
* <p>Alternatively, the internal BeanFactory exposed by the
* {@link ConfigurableApplicationContext} interface offers access to the
* AutowireCapableBeanFactory interface too. The present method mainly
* serves as convenient, specific facility on the ApplicationContext
* interface itself.
* @return the AutowireCapableBeanFactory for this context
* @throws IllegalStateException if the context does not support
* the AutowireCapableBeanFactory interface or does not hold an autowire-capable
* bean factory yet (usually if <code>refresh()</code> has never been called)
* @see ConfigurableApplicationContext#refresh()
* @see ConfigurableApplicationContext#getBeanFactory()
*/
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
以上是ApplicationContext的源码,她继承了相应的接口,ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver去进行相应的扩展。因此ApplicationContext增加了相应的很多功能。
如下:1.支持不同的信息源,因为他扩展了MessageSource接口,这个就支持了消息的国际化实现。2.支持相应的事件。因为继承了ApplicationEventPublisher,这样就为上下文提供了事件的机制。3.访问资源。这个体现在ResourceLoader和Resource的支持上,这样我们就可以在不同的地方得到bean定义的资源。
因此在我们使用的时候,一般都使用ApplicationContext作为IOC容器的基本形式。创建IOC容器。
ListableBeanFactory源码:
public interface ListableBeanFactory extends BeanFactory {
/**
* 检查beaFactory是否包含bean的定义 通过bean的name
* <p>Does not consider any hierarchy this factory may participate in,
* and ignores any singleton beans that have been registered by
* other means than bean definitions.
* @param beanName the name of the bean to look for
* @return if this bean factory contains a bean definition with the given name
* @see #containsBean
*/
boolean containsBeanDefinition(String beanName);
/**
* 返回在BeanFactory中存在的bean的定义的数量
* <p>Does not consider any hierarchy this factory may participate in,
* and ignores any singleton beans that have been registered by
* other means than bean definitions.
* @return the number of beans defined in the factory
*/
int getBeanDefinitionCount();
/**
* 返回所有关于bean定义的name
* <p>Does not consider any hierarchy this factory may participate in,
* and ignores any singleton beans that have been registered by
* other means than bean definitions.
* @return the names of all beans defined in this factory,
* or an empty array if none defined
*/
String[] getBeanDefinitionNames();
/**
* 返回bean的名称 通过bean定义的类型
* judging from either bean definitions or the value of <code>getObjectType</code>
* in the case of FactoryBeans.
* <p><b>NOTE: This method introspects top-level beans only.</b> It does <i>not</i>
* check nested beans which might match the specified type as well.
* <p>Does consider objects created by FactoryBeans, which means that FactoryBeans
* will get initialized. If the object created by the FactoryBean doesn't match,
* the raw FactoryBean itself will be matched against the type.
* <p>Does not consider any hierarchy this factory may participate in.
* Use BeanFactoryUtils' <code>beanNamesForTypeIncludingAncestors</code>
* to include beans in ancestor factories too.
* <p>Note: Does <i>not</i> ignore singleton beans that have been registered
* by other means than bean definitions.
* <p>This version of <code>getBeanNamesForType</code> matches all kinds of beans,
* be it singletons, prototypes, or FactoryBeans. In most implementations, the
* result will be the same as for <code>getBeanNamesOfType(type, true, true)</code>.
* <p>Bean names returned by this method should always return bean names <i>in the
* order of definition</i> in the backend configuration, as far as possible.
* @param type the class or interface to match, or <code>null</code> for all bean names
* @return the names of beans (or objects created by FactoryBeans) matching
* the given object type (including subclasses), or an empty array if none
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class)
*/
String[] getBeanNamesForType(Class type);
/**
* 返回bean的名称 通过bean定义的类型 (including subclasses),
* judging from either bean definitions or the value of <code>getObjectType</code>
* in the case of FactoryBeans.
* <p><b>NOTE: This method introspects top-level beans only.</b> It does <i>not</i>
* check nested beans which might match the specified type as well.
* <p>Does consider objects created by FactoryBeans if the "allowEagerInit" flag is set,
* which means that FactoryBeans will get initialized. If the object created by the
* FactoryBean doesn't match, the raw FactoryBean itself will be matched against the
* type. If "allowEagerInit" is not set, only raw FactoryBeans will be checked
* (which doesn't require initialization of each FactoryBean).
$ * <p>Does not consider any hierarchy this factory may participate in.
* Use BeanFactoryUtils' <code>beanNamesForTypeIncludingAncestors</code>
* to include beans in ancestor factories too.
* <p>Note: Does <i>not</i> ignore singleton beans that have been registered
* by other means than bean definitions.
* <p>Bean names returned by this method should always return bean names <i>in the
* order of definition</i> in the backend configuration, as far as possible.
* @param type the class or interface to match, or <code>null</code> for all bean names
* @param includeNonSingletons whether to include prototype or scoped beans too
* or just singletons (also applies to FactoryBeans)
* @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and
* <i>objects created by FactoryBeans</i> (or by factory methods with a
* "factory-bean" reference) for the type check. Note that FactoryBeans need to be
* eagerly initialized to determine their type: So be aware that passing in "true"
* for this flag will initialize FactoryBeans and "factory-bean" references.
* @return the names of beans (or objects created by FactoryBeans) matching
* the given object type (including subclasses), or an empty array if none
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)
*/
String[] getBeanNamesForType(Class type, boolean includeNonSingletons, boolean allowEagerInit);
/**
* 通过对象类型返回相应bean的实例 (including
* subclasses), judging from either bean definitions or the value of
* <code>getObjectType</code> in the case of FactoryBeans.
* <p><b>NOTE: This method introspects top-level beans only.</b> It does <i>not</i>
* check nested beans which might match the specified type as well.
* <p>Does consider objects created by FactoryBeans, which means that FactoryBeans
* will get initialized. If the object created by the FactoryBean doesn't match,
* the raw FactoryBean itself will be matched against the type.
* <p>Does not consider any hierarchy this factory may participate in.
* Use BeanFactoryUtils' <code>beansOfTypeIncludingAncestors</code>
* to include beans in ancestor factories too.
* <p>Note: Does <i>not</i> ignore singleton beans that have been registered
* by other means than bean definitions.
* <p>This version of getBeansOfType matches all kinds of beans, be it
* singletons, prototypes, or FactoryBeans. In most implementations, the
* result will be the same as for <code>getBeansOfType(type, true, true)</code>.
* <p>The Map returned by this method should always return bean names and
* corresponding bean instances <i>in the order of definition</i> in the
* backend configuration, as far as possible.
* @param type the class or interface to match, or <code>null</code> for all concrete beans
* @return a Map with the matching beans, containing the bean names as
* keys and the corresponding bean instances as values
* @throws BeansException if a bean could not be created
* @since 1.1.2
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class)
*/
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
/**
* 通过对象类型返回相应bean的实例 (including
* subclasses), judging from either bean definitions or the value of
* <code>getObjectType</code> in the case of FactoryBeans.
* <p><b>NOTE: This method introspects top-level beans only.</b> It does <i>not</i>
* check nested beans which might match the specified type as well.
* <p>Does consider objects created by FactoryBeans if the "allowEagerInit" flag is set,
* which means that FactoryBeans will get initialized. If the object created by the
* FactoryBean doesn't match, the raw FactoryBean itself will be matched against the
* type. If "allowEagerInit" is not set, only raw FactoryBeans will be checked
* (which doesn't require initialization of each FactoryBean).
* <p>Does not consider any hierarchy this factory may participate in.
* Use BeanFactoryUtils' <code>beansOfTypeIncludingAncestors</code>
* to include beans in ancestor factories too.
* <p>Note: Does <i>not</i> ignore singleton beans that have been registered
* by other means than bean definitions.
* <p>The Map returned by this method should always return bean names and
* corresponding bean instances <i>in the order of definition</i> in the
* backend configuration, as far as possible.
* @param type the class or interface to match, or <code>null</code> for all concrete beans
* @param includeNonSingletons whether to include prototype or scoped beans too
* or just singletons (also applies to FactoryBeans)
* @param allowEagerInit whether to initialize <i>lazy-init singletons</i> and
* <i>objects created by FactoryBeans</i> (or by factory methods with a
* "factory-bean" reference) for the type check. Note that FactoryBeans need to be
* eagerly initialized to determine their type: So be aware that passing in "true"
* for this flag will initialize FactoryBeans and "factory-bean" references.
* @return a Map with the matching beans, containing the bean names as
* keys and the corresponding bean instances as values
* @throws BeansException if a bean could not be created
* @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)
*/
<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
/*
* 查找所有的bean 通过注解
*Find all beans whose <code>Class</code> has the supplied {@link java.lang.annotation.Annotation} type.
* @param annotationType the type of annotation to look for
* @return a Map with the matching beans, containing the bean names as
* keys and the corresponding bean instances as values
* @throws BeansException if a bean could not be created
*/
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
throws BeansException;
/**
* Find a {@link Annotation} of <code>annotationType</code> on the specified
* bean, traversing its interfaces and super classes if no annotation can be
* found on the given class itself.
* @param beanName the name of the bean to look for annotations on
* @param annotationType the annotation class to look for
* @return the annotation of the given type found, or <code>null</code>
*/
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType);
}
HierarchicalBeanFactory源码:
public interface HierarchicalBeanFactory extends BeanFactory {
/**
* 返回父 bean factory, or <code>null</code> if there is none.
*/
BeanFactory getParentBeanFactory();
/**
* 返回本地是否存在bean的名称为name的bean
* ignoring beans defined in ancestor contexts.
* <p>This is an alternative to <code>containsBean</code>, ignoring a bean
* of the given name from an ancestor bean factory.
* @param name the name of the bean to query
* @return whether a bean with the given name is defined in the local factory
* @see org.springframework.beans.factory.BeanFactory#containsBean
*/
boolean containsLocalBean(String name);
}
MessageSource的源码:
public interface MessageSource {
/**
* Try to resolve the message. Return default message if no message was found.
* @param code the code to lookup up, such as 'calculator.noRateSet'. Users of
* this class are encouraged to base message names on the relevant fully
* qualified class name, thus avoiding conflict and ensuring maximum clarity.
* @param args array of arguments that will be filled in for params within
* the message (params look like "{0}", "{1,date}", "{2,time}" within a message),
* or <code>null</code> if none.
* @param defaultMessage String to return if the lookup fails
* @param locale the Locale in which to do the lookup
* @return the resolved message if the lookup was successful;
* otherwise the default message passed as a parameter
* @see java.text.MessageFormat
*/
String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
/**
* Try to resolve the message. Treat as an error if the message can't be found.
* @param code the code to lookup up, such as 'calculator.noRateSet'
* @param args Array of arguments that will be filled in for params within
* the message (params look like "{0}", "{1,date}", "{2,time}" within a message),
* or <code>null</code> if none.
* @param locale the Locale in which to do the lookup
* @return the resolved message
* @throws NoSuchMessageException if the message wasn't found
* @see java.text.MessageFormat
*/
String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;
/**
* Try to resolve the message using all the attributes contained within the
* <code>MessageSourceResolvable</code> argument that was passed in.
* <p>NOTE: We must throw a <code>NoSuchMessageException</code> on this method
* since at the time of calling this method we aren't able to determine if the
* <code>defaultMessage</code> property of the resolvable is null or not.
* @param resolvable value object storing attributes required to properly resolve a message
* @param locale the Locale in which to do the lookup
* @return the resolved message
* @throws NoSuchMessageException if the message wasn't found
* @see java.text.MessageFormat
*/
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}
ApplicationEventPublisher的源码:
public interface ApplicationEventPublisher {
/**
* Notify all listeners registered with this application of an application
* event. Events may be framework events (such as RequestHandledEvent)
* or application-specific events.
* @param event the event to publish
* @see org.springframework.web.context.support.RequestHandledEvent
*/
void publishEvent(ApplicationEvent event);
}
ResourcePatternResolver的源码:
public interface ResourcePatternResolver extends ResourceLoader {
/**
* Pseudo URL prefix for all matching resources from the class path: "classpath*:"
* This differs from ResourceLoader's classpath URL prefix in that it
* retrieves all matching resources for a given name (e.g. "/beans.xml"),
* for example in the root of all deployed JAR files.
* @see org.springframework.core.io.ResourceLoader#CLASSPATH_URL_PREFIX
*/
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
/**
* Resolve the given location pattern into Resource objects.
* <p>Overlapping resource entries that point to the same physical
* resource should be avoided, as far as possible. The result should
* have set semantics.
* @param locationPattern the location pattern to resolve
* @return the corresponding Resource objects
* @throws IOException in case of I/O errors
*/
Resource[] getResources(String locationPattern) throws IOException;
}
这个接口继承了ResourceLoader,所以让ApplicationContext也支持ResourceLoader和Resource.ResourceLoader里面有一个方法是得到Resource,可以看看:
public interface ResourceLoader {
/** Pseudo URL prefix for loading from the class path: "classpath:" */
String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
/**
* 通过资源的地址得到Resource
*/
Resource getResource(String location);
/**
* Expose the ClassLoader used by this ResourceLoader.
* <p>Clients which need to access the ClassLoader directly can do so
* in a uniform manner with the ResourceLoader, rather than relying
* on the thread context ClassLoader.
* @return the ClassLoader (never <code>null</code>)
*/
ClassLoader getClassLoader();
}
Spring源码解析-IOC容器的实现-ApplicationContext的更多相关文章
- Spring源码解析-ioc容器的设计
Spring源码解析-ioc容器的设计 1 IoC容器系列的设计:BeanFactory和ApplicatioContext 在Spring容器中,主要分为两个主要的容器系列,一个是实现BeanFac ...
- Spring源码解析-IOC容器的实现
1.IOC容器是什么? IOC(Inversion of Control)控制反转:本来是由应用程序管理的对象之间的依赖关系,现在交给了容器管理,这就叫控制反转,即交给了IOC容器,Spring的IO ...
- Spring 源码剖析IOC容器(一)概览
目录 一.容器概述 二.核心类源码解读 三.模拟容器获取Bean ======================= 一.容器概述 spring IOC控制反转,又称为DI依赖注入:大体是先初始化bean ...
- Spring源码阅读-IoC容器解析
目录 Spring IoC容器 ApplicationContext设计解析 BeanFactory ListableBeanFactory HierarchicalBeanFactory Messa ...
- Spring源码解析--IOC根容器Beanfactory详解
BeanFactory和FactoryBean的联系和区别 BeanFactory是整个Spring容器的根容器,里面描述了在所有的子类或子接口当中对容器的处理原则和职责,包括生命周期的一些约定. F ...
- [spring源码] 小白级别的源码解析IOC容器的依赖注入(三)
上一篇介绍了ioc容器的初始化过程,主要完成了ioc容器建立beanDefinition数据映射.并没有看到ioc容器对bean依赖关系进行注入. 接口getbean就是出发依赖注入发生的地方.下面从 ...
- Spring源码解析 – AnnotationConfigApplicationContext容器创建过程
Spring在BeanFactory基础上提供了一些列具体容器的实现,其中AnnotationConfigApplicationContext是一个用来管理注解bean的容器,从AnnotationC ...
- spring源码解析——2容器的基本实现(第2版笔记)
感觉第二版写的略潦草,就是在第一版的基础上加上了新的流行特性,比如idea,springboot,但是,潦草痕迹遍布字里行间. 虽然换成了idea,但是很多截图还是eclipse的,如果不是看了第一版 ...
- SPRING源码分析:IOC容器
在Spring中,最基本的IOC容器接口是BeanFactory - 这个接口为具体的IOC容器的实现作了最基本的功能规定 - 不管怎么着,作为IOC容器,这些接口你必须要满足应用程序的最基本要求: ...
随机推荐
- [转]loadrunner:系统的平均并发用户数和并发数峰值如何估算
一.经典公式1: 一般来说,利用以下经验公式进行估算系统的平均并发用户数和峰值数据 1)平均并发用户数为 C = nL/T 2)并发用户数峰值 C‘ = C + 3*根号C C是平均并发用户数,n是l ...
- JVM调优总结(转)
本文转自:http://my.oschina.net/xishuixixia/blog/132395 常用的调优参数. 1.堆大小 -Xms和-Xmx用于指定堆大小,我们需要将他们俩设置为一样的值,以 ...
- iOS知识点整理
1.宏定义 #define # ## a. 后面一个#是转成字符串 b. 后面## 是连接的作用 2. __attribute__ 常用的 __attribute__(( constructor ...
- JMeter的安装和目录解析
Ubuntu系统中jmeter的安装和目录解析 作为一个Linux新手,在使用jdk时,或许会安装配置多次仍然导致无法使用情况(如无法登录系统等),请按如下步骤一步一步安装并配置 相关软件下载地址 J ...
- 老话题之C#写邮件发送
唉!近来特么QQ邮件也犯二,突然间以前写的代码邮件发不出去,各种报错,无奈之下,换成了@163.com,可是报错依然,该开通(POP3/SMTP/IMAP)的都开通了!我勒了个草,像是在玩哥一样,还好 ...
- 20145329 《JAVA程序设计》课后习题代码编写总结
20145329<Java程序设计>课后习题学习总结 学习内容总结 package cc.openhome; public class Hello2 { public static voi ...
- 如何设置hyper-v下的ubuntu虚拟机分辨率
1.登陆ubuntu虚拟机 2.vi /etc/default/grub,改变如下内容: 改变前: GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" ...
- 爬虫框架Scrapy之Request/Response
Request yield scrapy.Request(url, self.parse) Request 源码: # 部分代码 class Request(object_ref): def __in ...
- Docker-Compose 一键部署Ningx+.Net Core+Redis集群
在看该文章前,你需要对Docker有所了解. 1.创建WebApp应用程序 我使用的是.Net Core 1.0.1版本,创建一个MVC应用程序,并添加对Redis的引用.因为这些很基础,也很简单,这 ...
- sql 取前一年、月
SQL SERVER 提供了一些时间函数:取当前时间:SELECT GETDATE() 取前一个月的时间:SELECT DATEADD(MONTH,-1,GETDATE()) 月份减一个月取年份:SE ...