#引言
spring做為java程式員必學的架構,從學校的課堂上,到實際工作中,都可以看到它的身影。之前看過一篇文章,說對于spring的源碼隻需要了解架構,不需要關注具體的實作,不敢苟同。如果對于java程式員最重要的架構都不關注具體實作,那麼還有什麼代碼值得去關注呢?有人說spring讓java程式員喪失了程式設計的能力,隻需要關注service,dao這些東西,那麼它給我們提供這些便利的背後到底做了什麼工作,如果能窺之一二,想想還有點小興奮呢。為了突出主題,就不介紹spring那些相關的概念了,看到spring,就提概念,真的很煩。QAQ
#整體介紹
spring的IOC容器可以簡單的看做一個map,當然實際要複雜的多。看做map有助于幫助我們了解spring的相關接口定義,spring中最重要的一個接口BeanFactory,BeanFactory定義了spring容器最基本也是最重要的能力。這麼重要當然的分析一下。
順便說一下,這裡spring的版本是4.3.15.RELEASE,最新的spring版本已經到5.+了,但是重要的部分變化不大。
public interface BeanFactory {
/**
* Used to dereference a {@link FactoryBean} instance and distinguish it from
* beans <i>created</i> by the FactoryBean. For example, if the bean named
* {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
* will return the factory, not the instance returned by the factory.
*
* 如果通過通過名稱去擷取bean,如果名稱以開頭&将擷取到FactoryBean本身而不是FactoryBean生産出的bean
* 順便提一句,FactoryBean是spring的一個接口,可以通過實作FactoryBean來注冊執行個體
*/
String FACTORY_BEAN_PREFIX = "&";
/**
* Return an instance, which may be shared or independent, of the specified bean.
* <p>This method allows a Spring BeanFactory to be used as a replacement for the
* Singleton or Prototype design pattern. Callers may retain references to
* returned objects in the case of Singleton beans.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to retrieve
* @return an instance of the bean
* @throws NoSuchBeanDefinitionException if there is no bean definition
* with the specified name
* @throws BeansException if the bean could not be obtained
*
*/
Object getBean(String name) throws BeansException;
/**
* Return an instance, which may be shared or independent, of the specified bean.
* <p>Behaves the same as {@link #getBean(String)}, but provides a measure of type
* safety by throwing a BeanNotOfRequiredTypeException if the bean is not of the
* required type. This means that ClassCastException can't be thrown on casting
* the result correctly, as can happen with {@link #getBean(String)}.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to retrieve
* @param requiredType type the bean must match. Can be an interface or superclass
* of the actual class, or {@code null} for any match. For example, if the value
* is {@code Object.class}, this method will succeed whatever the class of the
* returned instance.
* @return an instance of the bean
* @throws NoSuchBeanDefinitionException if there is no such bean definition
* @throws BeanNotOfRequiredTypeException if the bean is not of the required type
* @throws BeansException if the bean could not be created
*/
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
/**
* Return an instance, which may be shared or independent, of the specified bean.
* <p>Allows for specifying explicit constructor arguments / factory method arguments,
* overriding the specified default arguments (if any) in the bean definition.
* @param name the name of the bean to retrieve
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @return an instance of the bean
* @throws NoSuchBeanDefinitionException if there is no such bean definition
* @throws BeanDefinitionStoreException if arguments have been given but
* the affected bean isn't a prototype
* @throws BeansException if the bean could not be created
* @since 2.5
*/
Object getBean(String name, Object... args) throws BeansException;
/**
* Return the bean instance that uniquely matches the given object type, if any.
* <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
* but may also be translated into a conventional by-name lookup based on the name
* of the given type. For more extensive retrieval operations across sets of beans,
* use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
* @param requiredType type the bean must match; can be an interface or superclass.
* {@code null} is disallowed.
* @return an instance of the single bean matching the required type
* @throws NoSuchBeanDefinitionException if no bean of the given type was found
* @throws NoUniqueBeanDefinitionException if more than one bean of the given type was found
* @throws BeansException if the bean could not be created
* @since 3.0
* @see ListableBeanFactory
*/
<T> T getBean(Class<T> requiredType) throws BeansException;
/**
* Return an instance, which may be shared or independent, of the specified bean.
* <p>Allows for specifying explicit constructor arguments / factory method arguments,
* overriding the specified default arguments (if any) in the bean definition.
* <p>This method goes into {@link ListableBeanFactory} by-type lookup territory
* but may also be translated into a conventional by-name lookup based on the name
* of the given type. For more extensive retrieval operations across sets of beans,
* use {@link ListableBeanFactory} and/or {@link BeanFactoryUtils}.
* @param requiredType type the bean must match; can be an interface or superclass.
* {@code null} is disallowed.
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @return an instance of the bean
* @throws NoSuchBeanDefinitionException if there is no such bean definition
* @throws BeanDefinitionStoreException if arguments have been given but
* the affected bean isn't a prototype
* @throws BeansException if the bean could not be created
* @since 4.1
*/
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
/**
* Does this bean factory contain a bean definition or externally registered singleton
* instance with the given name?
* <p>If the given name is an alias, it will be translated back to the corresponding
* canonical bean name.
* <p>If this factory is hierarchical, will ask any parent factory if the bean cannot
* be found in this factory instance.
* <p>If a bean definition or singleton instance matching the given name is found,
* this method will return {@code true} whether the named bean definition is concrete
* or abstract, lazy or eager, in scope or not. Therefore, note that a {@code true}
* return value from this method does not necessarily indicate that {@link #getBean}
* will be able to obtain an instance for the same name.
* @param name the name of the bean to query
* @return whether a bean with the given name is present
*/
boolean containsBean(String name);
/**
* Is this bean a shared singleton? That is, will {@link #getBean} always
* return the same instance?
* <p>Note: This method returning {@code false} does not clearly indicate
* independent instances. It indicates non-singleton instances, which may correspond
* to a scoped bean as well. Use the {@link #isPrototype} operation to explicitly
* check for independent instances.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @return whether this bean corresponds to a singleton instance
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @see #getBean
* @see #isPrototype
*/
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
/**
* Is this bean a prototype? That is, will {@link #getBean} always return
* independent instances?
* <p>Note: This method returning {@code false} does not clearly indicate
* a singleton object. It indicates non-independent instances, which may correspond
* to a scoped bean as well. Use the {@link #isSingleton} operation to explicitly
* check for a shared singleton instance.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @return whether this bean will always deliver independent instances
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 2.0.3
* @see #getBean
* @see #isSingleton
*/
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
/**
* Check whether the bean with the given name matches the specified type.
* More specifically, check whether a {@link #getBean} call for the given name
* would return an object that is assignable to the specified target type.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @param typeToMatch the type to match against (as a {@code ResolvableType})
* @return {@code true} if the bean type matches,
* {@code false} if it doesn't match or cannot be determined yet
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 4.2
* @see #getBean
* @see #getType
*/
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
/**
* Check whether the bean with the given name matches the specified type.
* More specifically, check whether a {@link #getBean} call for the given name
* would return an object that is assignable to the specified target type.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @param typeToMatch the type to match against (as a {@code Class})
* @return {@code true} if the bean type matches,
* {@code false} if it doesn't match or cannot be determined yet
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 2.0.1
* @see #getBean
* @see #getType
*/
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
/**
* Determine the type of the bean with the given name. More specifically,
* determine the type of object that {@link #getBean} would return for the given name.
* <p>For a {@link FactoryBean}, return the type of object that the FactoryBean creates,
* as exposed by {@link FactoryBean#getObjectType()}.
* <p>Translates aliases back to the corresponding canonical bean name.
* Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the name of the bean to query
* @return the type of the bean, or {@code null} if not determinable
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 1.1.2
* @see #getBean
* @see #isTypeMatch
*/
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
/**
* Return the aliases for the given bean name, if any.
* All of those aliases point to the same bean when used in a {@link #getBean} call.
* <p>If the given name is an alias, the corresponding original bean name
* and other aliases (if any) will be returned, with the original bean name
* being the first element in the array.
* <p>Will ask the parent factory if the bean cannot be found in this factory instance.
* @param name the bean name to check for aliases
* @return the aliases, or an empty array if none
* @see #getBean
*/
String[] getAliases(String name);
我也不想貼代碼的QAQ,但這個接口很是重要,以後都要圍繞它展開。如果要你給這個接口添加個實作類,是不是馬上想到一個或者幾個map就能搞定了?是以再有人問你能不能自己實作個spring,堅定告訴他可以!
有了源頭BeanFactory,很自然的出現了很多“目的地”,可以看出,BeanFactory大緻“流"向了兩個方向。一個是Factory方向,一個ApplicationContext方向。Factory方向關注的更多的是bean建立的加強,而applicationContext方向更多的關注的是一些額外的“裝飾”,比如國際化MessageSource,事件的分發ApplicationEventPublisher。就像程式員常常需要面對的一個問題:“往深度發展還是往廣度發展?”。程式是人寫出來的,肯定處處包含人類社會發展的規律,扯遠了…
下面先看下spring是如何對BeanFactory進行增強的:
- HierarchicalBeanFactory
public interface HierarchicalBeanFactory extends BeanFactory {
/**
* Return the parent bean factory, or {@code null} if there is none.
*
* 擷取父容器
*/
BeanFactory getParentBeanFactory();
/**
* 目前容器是否包含某個執行個體
*/
boolean containsLocalBean(String name);
}
- ListableBeanFactory
public interface ListableBeanFactory extends BeanFactory {
/**
* 是否包含bean的BeanDefinition
*/
boolean containsBeanDefinition(String beanName);
/**
* 擷取bean的BeanDefinition的數量
*/
int getBeanDefinitionCount();
/**
* 擷取BeanDefinition的names
*/
String[] getBeanDefinitionNames();
/**
* 擷取指定類型的bean的名稱
*/
String[] getBeanNamesForType(ResolvableType type);
/**
* 擷取指定類型bean的名稱
*/
String[] getBeanNamesForType(Class<?> type);
/**
* 擷取指定類型bean的名稱
*/
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
/**
* 擷取指定類型的bean的執行個體
*/
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;
/**
* 擷取指定類型的bean的執行個體
*/
<T> Map<String, T> getBeansOfType(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;
/**
* 擷取指定名稱類上的注解執行個體
*/
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
可以看出ListableBeanFactory是相當重要的一個接口,賦予了beanFactory将解析的Bean的資訊存儲及擷取的能力。
- AutowireCapableBeanFactory
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;
//-------------------------------------------------------------------------
// Typical methods for creating and populating external bean instances
//-------------------------------------------------------------------------
/**
* 根據類型建立bean
*/
<T> T createBean(Class<T> beanClass) throws BeansException;
/**
* 觸發指定的bean的依賴注入
*/
void autowireBean(Object existingBean) throws BeansException;
/**
* 配置指定的bean,包括自動注入屬性,設定屬性的值,調用beanFactory的回調,例如 setBeanFactory,
* 執行相關後置處理器
*/
Object configureBean(Object existingBean, String beanName) throws BeansException;
//-------------------------------------------------------------------------
// Specialized methods for fine-grained control over the bean lifecycle
//-------------------------------------------------------------------------
/**
* 建立bean的執行個體
*/
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
/**
* 建立指定類型的bean執行個體,并進行依賴注入
*/
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
/**
* 設定指定bean執行個體的屬性
*/
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;
/**
* 設定指定bean執行個體的屬性,并不觸發依賴注入
*/
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
/**
* 初始化指定bean執行個體,包括調用beanFactory相關回調,處理後置處理器等。
*/
Object initializeBean(Object existingBean, String beanName) throws BeansException;
/**
* 在bean執行個體化之前觸發指定bean執行個體的處理器
*/
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
/**
* 在bean執行個體化之後觸發指定bean執行個體的處理器
*/
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
/**
* 銷毀指定bean執行個體
*/
void destroyBean(Object existingBean);
//-------------------------------------------------------------------------
// Delegate methods for resolving injection points
//-------------------------------------------------------------------------
/**
* 根據類型解析成為相應的NamedBeanHolder
*/
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
/**
* 根據DependencyDescriptor 解析注入的類執行個體
*/
Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException;
/**
* 根據DependencyDescriptor 解析注入的類執行個體
*/
Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;
AutowireCapableBeanFactory賦予了BeanFactory依賴注入的能力。
- ConfigurableBeanFactory
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
/**
* 單例标志
*/
String SCOPE_SINGLETON = "singleton";
/**
* 原型标志
*/
String SCOPE_PROTOTYPE = "prototype";
/**
* 設定父BeanFactory
*/
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
/**
* 設定ClassLoader
*/
void setBeanClassLoader(ClassLoader beanClassLoader);
/**
* 擷取ClassLoader
*/
ClassLoader getBeanClassLoader();
/**
* 設定臨時的ClassLoader用作類型比對
*/
void setTempClassLoader(ClassLoader tempClassLoader);
/**
* 擷取臨時的ClassLoader
*/
ClassLoader getTempClassLoader();
/**
* 設定是否緩存Bean的中繼資料
*/
void setCacheBeanMetadata(boolean cacheBeanMetadata);
/**
* 擷取是否緩存Bean的中繼資料
*/
boolean isCacheBeanMetadata();
/**
*
* 指定bean表達式解析器,預設沒有,ApplicationContext會預設指定一個标準的政策,支援el表達式
*/
void setBeanExpressionResolver(BeanExpressionResolver resolver);
/**
* 擷取bean表達式解析器
*/
BeanExpressionResolver getBeanExpressionResolver();
/**
* 指定bean屬性的轉化service
*/
void setConversionService(ConversionService conversionService);
/**
* 擷取bean屬性轉化service
*/
ConversionService getConversionService();
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
/**
* 注冊屬性Editor
*/
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
/**
* Initialize the given PropertyEditorRegistry with the custom editors
* that have been registered with this BeanFactory.
* @param registry the PropertyEditorRegistry to initialize
*/
void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
/**
* 設定類型轉換器
*/
void setTypeConverter(TypeConverter typeConverter);
/**
* 擷取類型轉換器
*/
TypeConverter getTypeConverter();
/**
* Add a String resolver for embedded values such as annotation attributes.
* @param valueResolver the String resolver to apply to embedded values
* @since 3.0
*/
void addEmbeddedValueResolver(StringValueResolver valueResolver);
/**
* Determine whether an embedded value resolver has been registered with this
* bean factory, to be applied through {@link #resolveEmbeddedValue(String)}.
* @since 4.3
*/
boolean hasEmbeddedValueResolver();
/**
* Resolve the given embedded value, e.g. an annotation attribute.
* @param value the value to resolve
* @return the resolved value (may be the original value as-is)
* @since 3.0
*/
String resolveEmbeddedValue(String value);
/**
* 添加bean後置處理器
*/
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
/**
* 擷取bean後置處理器的數量
*/
int getBeanPostProcessorCount();
/**
* Register the given scope, backed by the given Scope implementation.
*/
void registerScope(String scopeName, Scope scope);
/**
* Return the names of all currently registered scopes.
* <p>This will only return the names of explicitly registered scopes.
* Built-in scopes such as "singleton" and "prototype" won't be exposed.
*/
String[] getRegisteredScopeNames();
/**
* Return the Scope implementation for the given scope name, if any.
* <p>This will only return explicitly registered scopes.
* Built-in scopes such as "singleton" and "prototype" won't be exposed.
*/
Scope getRegisteredScope(String scopeName);
/**
* Provides a security access control context relevant to this factory.
*/
AccessControlContext getAccessControlContext();
/**
* 從其他beanFactory複制配置值
*/
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
/**
* 配置别名
*/
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
/**
* 解析别名
*/
void resolveAliases(StringValueResolver valueResolver);
/**
* Return a merged BeanDefinition for the given bean name,
* merging a child bean definition with its parent if necessary.
* Considers bean definitions in ancestor factories as well.
*/
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* Determine whether the bean with the given name is a FactoryBean.
*/
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;
/**
* 設定指定名稱的bean是否是正在建立的狀态
*/
void setCurrentlyInCreation(String beanName, boolean inCreation);
/**
* Determine whether the specified bean is currently in creation.
*/
boolean isCurrentlyInCreation(String beanName);
/**
* 設定指定的bean依賴的bean的名稱
*
*/
void registerDependentBean(String beanName, String dependentBeanName);
/**
* Return the names of all beans which depend on the specified bean, if any.
*/
String[] getDependentBeans(String beanName);
/**
* Return the names of all beans that the specified bean depends on, if any.
*/
String[] getDependenciesForBean(String beanName);
/**
* Destroy the given bean instance (usually a prototype instance
* obtained from this factory) according to its bean definition.
* <p>Any exception that arises during destruction should be caught
* and logged instead of propagated to the caller of this method.
*/
void destroyBean(String beanName, Object beanInstance);
/**
* Destroy the specified scoped bean in the current target scope, if any.
* <p>Any exception that arises during destruction should be caught
* and logged instead of propagated to the caller of this method.
*/
void destroyScopedBean(String beanName);
/**
* Destroy all singleton beans in this factory, including inner beans that have
* been registered as disposable. To be called on shutdown of a factory.
* <p>Any exception that arises during destruction should be caught
* and logged instead of propagated to the caller of this method.
*/
void destroySingletons();
}
ConfigurableBeanFactory定義了BeanFactory的各種配置項。
- ConfigurableListableBeanFactory
public interface ConfigurableListableBeanFactory
extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
/**
* 需要忽略依賴注入的類型
*/
void ignoreDependencyType(Class<?> type);
/**
* 需要忽略依賴注入的接口
*/
void ignoreDependencyInterface(Class<?> ifc);
/**
* Register a special dependency type with corresponding autowired value.
* <p>This is intended for factory/context references that are supposed
* to be autowirable but are not defined as beans in the factory:
* e.g. a dependency of type ApplicationContext resolved to the
* ApplicationContext instance that the bean is living in.
* <p>Note: There are no such default types registered in a plain BeanFactory,
* not even for the BeanFactory interface itself.
*
* 将指定類型和指定類型的bean的執行個體化對象注冊進beanFactory,為了需要依賴注入此bean但是beanFactory并沒有此種
* 類型的情況下
*/
void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);
/**
* Determine whether the specified bean qualifies as an autowire candidate,
* to be injected into other beans which declare a dependency of matching type.
* <p>This method checks ancestor factories as well.
*/
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
throws NoSuchBeanDefinitionException;
/**
* 擷取值定名稱的BeanDefinition
*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
Iterator<String> getBeanNamesIterator();
void clearMetadataCache();
/**
* 當機所有的beanDefifition
*/
void freezeConfiguration();
/**
* Return whether this factory's bean definitions are frozen,
* i.e. are not supposed to be modified or post-processed any further.
*/
boolean isConfigurationFrozen();
/**
* 初始化所有的單例bean
*/
void preInstantiateSingletons() throws BeansException;
}
接下來我們再看下spring是如何對beanFactory進行"裝飾"的:
- ResourceLoader
public interface ResourceLoader {
/** Pseudo URL prefix for loading from the class path: "classpath:" */
String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
/**
* 擷取指定路徑的資源資訊
*/
Resource getResource(String location);
ClassLoader getClassLoader();
}
- ResourcePatternResolver
public interface ResourcePatternResolver extends ResourceLoader {
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
/**
* 根據比對表達式擷取規則
*/
Resource[] getResources(String locationPattern) throws IOException;
}
-EnvironmentCapable
public interface EnvironmentCapable {
/**
* 擷取環境資訊
*/
Environment getEnvironment();
}
-MessageSource
public interface MessageSource {
/**
* 擷取國際化消息
*/
String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
/**
* 擷取國際化消息
*/
String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;
/**
* 擷取國際化消息
*/
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}
- ApplicationEventPublisher
public interface ApplicationEventPublisher {
/**
* 釋出事件
*/
void publishEvent(ApplicationEvent event);
void publishEvent(Object event);
}
接下來就是重量級的接口ApplicationContext
-ApplicationContext
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
/**
* 容器辨別
*/
String getId();
String getApplicationName();
String getDisplayName();
long getStartupDate();
/**
* 擷取父類容器
*/
ApplicationContext getParent();
/**
* 擷取BeanFactory,通過這個方法可以看出ApplicationContext的實作類不是通過繼承BeanFatory來擴充功能的,
* 而是通過持有BeanFatory的執行個體來擴充功能的。
*/
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
- WebApplicationContext
public interface WebApplicationContext extends ApplicationContext {
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
/**
* Scope identifier for request scope: "request".
*/
String SCOPE_REQUEST = "request";
/**
* Scope identifier for session scope: "session".
*/
String SCOPE_SESSION = "session";
/**
* Scope identifier for global session scope: "globalSession".
*/
String SCOPE_GLOBAL_SESSION = "globalSession";
/**
* Scope identifier for the global web application scope: "application".
*/
String SCOPE_APPLICATION = "application";
/**
* Name of the ServletContext environment bean in the factory.
*/
String SERVLET_CONTEXT_BEAN_NAME = "servletContext";
/**
* Name of the ServletContext/PortletContext init-params environment bean in the factory.
*/
String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";
/**
* Name of the ServletContext/PortletContext attributes environment bean in the factory.
*/
String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";
/**
* 擷取servlet上下文資訊
*/
ServletContext getServletContext();
}
WebApplicationContext是對ApplicationContext的擴充
- ConfigurableApplicationContext
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
/**
* 路徑分隔符
*/
String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
/**
* 類型轉換服務名字
*/
String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
/**
* 預設代碼織入名字
*/
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
String ENVIRONMENT_BEAN_NAME = "environment";
String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
void setId(String id);
void setParent(ApplicationContext parent);
@Override
ConfigurableEnvironment getEnvironment();
void setEnvironment(ConfigurableEnvironment environment);
/**
* 添加beanFactory後置處理器
*/
void addBeanFactoryPostProcessor(BeanFactoryPostProcessor beanFactoryPostProcessor);
/**
* 添加容器的監聽器
*/
void addApplicationListener(ApplicationListener<?> listener);
/**
* 重新整理容器
*/
void refresh() throws BeansException, IllegalStateException;
/**
* 注冊jvm關閉時的鈎子函數
*/
void registerShutdownHook();
/**
* 關閉容器
*/
@Override
void close();
/**
* 容器是否正在運作
*/
boolean isActive();
ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}
- ConfigurableWebApplicationContext
public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext {
String APPLICATION_CONTEXT_ID_PREFIX = WebApplicationContext.class.getName() + ":";
String SERVLET_CONFIG_BEAN_NAME = "servletConfig";
void setServletContext(ServletContext servletContext);
void setServletConfig(ServletConfig servletConfig);
ServletConfig getServletConfig();
/**
* 設定命名空間
*/
void setNamespace(String namespace);
String getNamespace();
/**
* 設定配置檔案的路徑
*/
void setConfigLocation(String configLocation);
void setConfigLocations(String... configLocations);
String[] getConfigLocations();
}
通過分析接口我們大概可以看出整個spring容器的結構,接口中出現的類有些可能不認識,我們之後再一一分析。