以打卡的方式阅读Spring源码.简单的一天打卡好几个,复杂的就多花几天.
1. BeanFactory
package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
/**
* The root interface for accessing a Spring bean container.
* This is the basic client view of a bean container;
* further interfaces such as {@link ListableBeanFactory} and
* {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
* are available for specific purposes.
*
*访问Spring bean容器的根接口, 容器是用来管理bean的生命周期的(创建、销毁),有了容器,我们就不需
*要自己去手动new一个对象,只需要调用容器的getBean即可。
*
* <p>This interface is implemented by objects that hold a number of bean definitions,
* each uniquely identified by a String name. Depending on the bean definition,
* the factory will return either an independent instance of a contained object
* (the Prototype design pattern), or a single shared instance (a superior
* alternative to the Singleton design pattern, in which the instance is a
* singleton in the scope of the factory). Which type of instance will be returned
* depends on the bean factory configuration: the API is the same. Since Spring
* 2.0, further scopes are available depending on the concrete application
* context (e.g. "request" and "session" scopes in a web environment).
*
*这个接口的实现类持有一定数量的bean定义, 每个bean定义有一个唯一的字符串名字.
*基于bean定义,工厂可以返回一个独立的实例或者容器对象(也就是bean)
*这些bean可以是单例、原型、甚至是扩展的session、request.
*这是对BeanFactory的实现类的展望,大概说了下原理,实际上比这个复杂
*
* <p>The point of this approach is that the BeanFactory is a central registry
* of application components, and centralizes configuration of application
* components (no more do individual objects need to read properties files,
* for example). See chapters 4 and 11 of "Expert One-on-One J2EE Design and
* Development" for a discussion of the benefits of this approach.
*
*BeanFactory 是 应用组件的注册中心, 和配置中心(其他的类不需要再读配置文件了,如果需要的话,
*找Spring要就好了). 推荐阅读“Expert One-on-One J2EE”, 了解这种方式的好处。好处?
*百度上很多,什么低侵入啊、解耦合啊、方便测试啊,等等。
*
* <p>Note that it is generally better to rely on Dependency Injection
* ("push" configuration) to configure application objects through setters
* or constructors, rather than use any form of "pull" configuration like a
* BeanFactory lookup. Spring's Dependency Injection functionality is
* implemented using this BeanFactory interface and its subinterfaces.
*
*依赖注入,比依赖查找(比如jndi)好
*
* <p>Normally a BeanFactory will load bean definitions stored in a configuration
* source (such as an XML document), and use the {@code org.springframework.beans}
* package to configure the beans. However, an implementation could simply return
* Java objects it creates as necessary directly in Java code. There are no
* constraints on how the definitions could be stored: LDAP, RDBMS, XML,
* properties file, etc. Implementations are encouraged to support references
* amongst beans (Dependency Injection).
*
*一个BeanFactory 的实现类会加载配置源中的bean定义,用{@code org.springframework.beans}这个
*包来配置这些beans.
*一个BeanFactory 的实现类,在调用getBean的时候,会直接返回java对象.
*这些bean定义的配置可以存放在:LDAP RDBMS XML 配置文件,等等.
*
* <p>In contrast to the methods in {@link ListableBeanFactory}, all of the
* operations in this interface will also check parent factories if this is a
* {@link HierarchicalBeanFactory}. If a bean is not found in this factory instance,
* the immediate parent factory will be asked. Beans in this factory instance
* are supposed to override beans of the same name in any parent factory.
*
*HierarchicalBeanFactory这个接口,所有在BeanFactory中的操作,还会检查parent 工厂.
*
* <p>Bean factory implementations should support the standard bean lifecycle interfaces
* as far as possible. The full set of initialization methods and their standard order is:
*
*Bean 工厂的实现类应该尽可能多的支持标准的bean生命周期的接口,包括初始化方法和销毁方法.
*
* <ol>
* <li>BeanNameAware's {@code setBeanName}
* <li>BeanClassLoaderAware's {@code setBeanClassLoader}
* <li>BeanFactoryAware's {@code setBeanFactory}
* <li>EnvironmentAware's {@code setEnvironment}
* <li>EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
* <li>ResourceLoaderAware's {@code setResourceLoader}
* (only applicable when running in an application context)
* <li>ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
* (only applicable when running in an application context)
* <li>MessageSourceAware's {@code setMessageSource}
* (only applicable when running in an application context)
* <li>ApplicationContextAware's {@code setApplicationContext}
* (only applicable when running in an application context)
* <li>ServletContextAware's {@code setServletContext}
* (only applicable when running in a web application context)
* <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
* <li>InitializingBean's {@code afterPropertiesSet}
* <li>a custom init-method definition
* <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
* </ol>
*
* <p>On shutdown of a bean factory, the following lifecycle methods apply:
* <ol>
* <li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
* <li>DisposableBean's {@code destroy}
* <li>a custom destroy-method definition
* </ol>
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @since 13 April 2001
* @see BeanNameAware#setBeanName
* @see BeanClassLoaderAware#setBeanClassLoader
* @see BeanFactoryAware#setBeanFactory
* @see org.springframework.context.ResourceLoaderAware#setResourceLoader
* @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher
* @see org.springframework.context.MessageSourceAware#setMessageSource
* @see org.springframework.context.ApplicationContextAware#setApplicationContext
* @see org.springframework.web.context.ServletContextAware#setServletContext
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
* @see InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
* @see DisposableBean#destroy
* @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName
*/
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.
*
*比如myJndiObject是通过自定义的工厂方法生成的,&myJndiObject可以获取这个工厂.
*
*/
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 with the specified name
* @throws BeansException if the bean could not be obtained
*
*返回的对象,可以是单例的、也可以是原型.如果用的别名,会被翻译成原名.如果本工厂不存在,还会去
*parent 工厂查找.
*/
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
* @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
*
* 多了一个requiredType的参数,如果类型不匹配,则抛出BeanNotOfRequiredTypeException
*/
<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
*
* 后面的args是干什么的呢,是用来传递给构造器或者工厂方法作为参数的.
*/
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
* @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
*
* 没错,既然可以通过beanName查找,为什么不能通过requiredType查找呢.
* 返回的可以是接口的实现类、或者子类.
*/
<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
* @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;
/**
* Return an provider for the specified bean, allowing for lazy on-demand retrieval
* of instances, including availability and uniqueness options.
* @param requiredType type the bean must match; can be an interface or superclass
* @return a corresponding provider handle
* @since 5.1
* @see #getBeanProvider(ResolvableType)
*
*
*/
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
/**
* Return an provider for the specified bean, allowing for lazy on-demand retrieval
* of instances, including availability and uniqueness options.
* @param requiredType type the bean must match; can be a generic type declaration.
* Note that collection types are not supported here, in contrast to reflective
* injection points. For programmatically retrieving a list of beans matching a
* specific type, specify the actual bean type as an argument here and subsequently
* use {@link ObjectProvider#orderedStream()} or its lazy streaming/iteration options.
* @return a corresponding provider handle
* @since 5.1
* @see ObjectProvider#iterator()
* @see ObjectProvider#stream()
* @see ObjectProvider#orderedStream()
*
* 返回指定bean的一个提供者,允许懒的俺需获取,包括可用性和唯一性选项.
* 注意:requiredType是bean一定要匹配的; 对于编程方式获取一个指定类型的bean的列表,
* 指定requiredType,然后用流或者迭代器获取到这些bean.
* 通常情况,我们是这么用依赖注入的
* @Auwire
* private IUserService userService;
* 如果容器没有IUserService 的实现类,或者有多个,Spring容器启动过程就会报错;
* 但是,可以这么写:
* @Auwire
* private ObjectProvider<IUserService> userServiceObjectProvider;
* 然后在程序中判断,是否有IUserService,或者有多个.
*/
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
/**
* 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
*
* 如果name是别名,翻译成原名;如果本beanFacotry不存在,去parent factory查找.
* 是singleton返回true, 不是返回false, 不存在抛出异常
*/
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
*/
@Nullable
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);
}
总结:代码很少,备注中对BeanFactory的实现类做了一些规定,或者说约束.
2.ObjectFactory
/**
* Defines a factory which can return an Object instance
* (possibly shared or independent) when invoked.
*
* <p>This interface is typically used to encapsulate a generic factory which
* returns a new instance (prototype) of some target object on each invocation.
*
* <p>This interface is similar to {@link FactoryBean}, but implementations
* of the latter are normally meant to be defined as SPI instances in a
* {@link BeanFactory}, while implementations of this class are normally meant
* to be fed as an API to other beans (through injection). As such, the
* {@code getObject()} method has different exception handling behavior.
*
* 定义一个工厂,调用的时候返回一个对象(可能是共享的或者独立的)(singlton or prototype)
* 通常用来封装一个通用工厂, 每次调用返回一个新的实例.
*
* ObjectFactory与FactoryBean的区别:
* FactoryBean是典型的工厂模式,你给我一个beanName,我返回给你一个bean.
* ObjectFactory是对对象创建的过程的封装,一个典型的应用是:
* ObjectFactory借助Scope接口自定义scope 你可以控制对象的创建时机(session, request)
*
* @author Colin Sampaleanu
* @since 1.0.2
* @param <T> the object type
* @see FactoryBean
*/
@FunctionalInterface
public interface ObjectFactory<T> {
/**
* Return an instance (possibly shared or independent)
* of the object managed by this factory.
* @return the resulting instance
* @throws BeansException in case of creation errors
*/
T getObject() throws BeansException;
}
3.ObjectProvider
package org.springframework.beans.factory;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;
/**
* A variant of {@link ObjectFactory} designed specifically for injection points,
* allowing for programmatic optionality and lenient not-unique handling.
*
*一个ObjectFactory的变种, 专门设计用来注入点(依赖注入),允许编程方式处理可选性和非唯一性.
*
* <p>As of 5.1, this interface extends {@link Iterable} and provides {@link Stream}
* support. It can be therefore be used in {@code for} loops, provides {@link #forEach}
* iteration and allows for collection-style {@link #stream} access.
*
* @author Juergen Hoeller
* @since 4.3
* @param <T> the object type
* @see BeanFactory#getBeanProvider
* @see org.springframework.beans.factory.annotation.Autowired
*/
public interface ObjectProvider<T> extends ObjectFactory<T>, Iterable<T> {
/**
* Return an instance (possibly shared or independent) of the object
* managed by this factory.
* <p>Allows for specifying explicit construction arguments, along the
* lines of {@link BeanFactory#getBean(String, Object...)}.
* @param args arguments to use when creating a corresponding instance
* @return an instance of the bean
* @throws BeansException in case of creation errors
* @see #getObject()
*
* 获取一个对象, args是用来传给构造器或者工厂方法的.
*/
T getObject(Object... args) throws BeansException;
/**
* Return an instance (possibly shared or independent) of the object
* managed by this factory.
* @return an instance of the bean, or {@code null} if not available
* @throws BeansException in case of creation errors
* @see #getObject()
*
* 有就返回,没有就返回null,创建时异常返回BeansException.
*/
@Nullable
T getIfAvailable() throws BeansException;
/**
* Return an instance (possibly shared or independent) of the object
* managed by this factory.
* @param defaultSupplier a callback for supplying a default object
* if none is present in the factory
* @return an instance of the bean, or the supplied default object
* if no such bean is available
* @throws BeansException in case of creation errors
* @since 5.0
* @see #getIfAvailable()
*/
default T getIfAvailable(Supplier<T> defaultSupplier) throws BeansException {
T dependency = getIfAvailable();
return (dependency != null ? dependency : defaultSupplier.get());
}
/**
* Consume an instance (possibly shared or independent) of the object
* managed by this factory, if available.
* @param dependencyConsumer a callback for processing the target object
* if available (not called otherwise)
* @throws BeansException in case of creation errors
* @since 5.0
* @see #getIfAvailable()
*/
default void ifAvailable(Consumer<T> dependencyConsumer) throws BeansException {
T dependency = getIfAvailable();
if (dependency != null) {
dependencyConsumer.accept(dependency);
}
}
/**
* Return an instance (possibly shared or independent) of the object
* managed by this factory.
* @return an instance of the bean, or {@code null} if not available or
* not unique (i.e. multiple candidates found with none marked as primary)
* @throws BeansException in case of creation errors
* @see #getObject()
*/
@Nullable
T getIfUnique() throws BeansException;
/**
* Return an instance (possibly shared or independent) of the object
* managed by this factory.
* @param defaultSupplier a callback for supplying a default object
* if no unique candidate is present in the factory
* @return an instance of the bean, or the supplied default object
* if no such bean is available or if it is not unique in the factory
* (i.e. multiple candidates found with none marked as primary)
* @throws BeansException in case of creation errors
* @since 5.0
* @see #getIfUnique()
*/
default T getIfUnique(Supplier<T> defaultSupplier) throws BeansException {
T dependency = getIfUnique();
return (dependency != null ? dependency : defaultSupplier.get());
}
/**
* Consume an instance (possibly shared or independent) of the object
* managed by this factory, if unique.
* @param dependencyConsumer a callback for processing the target object
* if unique (not called otherwise)
* @throws BeansException in case of creation errors
* @since 5.0
* @see #getIfAvailable()
*/
default void ifUnique(Consumer<T> dependencyConsumer) throws BeansException {
T dependency = getIfUnique();
if (dependency != null) {
dependencyConsumer.accept(dependency);
}
}
/**
* Return an {@link Iterator} over all matching object instances,
* without specific ordering guarantees (but typically in registration order).
* @since 5.1
* @see #stream()
*/
@Override
default Iterator<T> iterator() {
return stream().iterator();
}
/**
* Return a sequential {@link Stream} over all matching object instances,
* without specific ordering guarantees (but typically in registration order).
* @since 5.1
* @see #iterator()
* @see #orderedStream()
*/
default Stream<T> stream() {
throw new UnsupportedOperationException("Multi element access not supported");
}
/**
* Return a sequential {@link Stream} over all matching object instances,
* pre-ordered according to the factory's common order comparator.
* <p>In a standard Spring application context, this will be ordered
* according to {@link org.springframework.core.Ordered} conventions,
* and in case of annotation-based configuration also considering the
* {@link org.springframework.core.annotation.Order} annotation,
* analogous to multi-element injection points of list/array type.
* @since 5.1
* @see #stream()
* @see org.springframework.core.OrderComparator
*/
default Stream<T> orderedStream() {
throw new UnsupportedOperationException("Ordered element access not supported");
}
}