1.beanDefinition
查看代码
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
//单例
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
//原型
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
/**
* Role hint indicating that a {@code BeanDefinition} is a major part
* of the application. Typically corresponds to a user-defined bean.
*/
int ROLE_APPLICATION = 0;
/**
* Role hint indicating that a {@code BeanDefinition} is a supporting
* part of some larger configuration, typically an outer
* {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
* {@code SUPPORT} beans are considered important enough to be aware
* of when looking more closely at a particular
* {@link org.springframework.beans.factory.parsing.ComponentDefinition},
* but not when looking at the overall configuration of an application.
*/
int ROLE_SUPPORT = 1;
/**
* Role hint indicating that a {@code BeanDefinition} is providing an
* entirely background role and has no relevance to the end-user. This hint is
* used when registering beans that are completely part of the internal workings
* of a {@link org.springframework.beans.factory.parsing.ComponentDefinition}.
*/
int ROLE_INFRASTRUCTURE = 2;
// Modifiable attributes
//设置父的BeanDefinition名称
void setParentName(@Nullable String parentName);
//获取父的BeanDefinition名称
String getParentName();
//设置beanClass名称
void setBeanClassName(@Nullable String beanClassName);
//获取beanClass名称
@Nullable
String getBeanClassName();
//设置作用域
void setScope(@Nullable String scope);
//获取作用域
@Nullable
String getScope();
//设置是否懒加载
void setLazyInit(boolean lazyInit);
//是懒加载
boolean isLazyInit();
//设置依赖,对应xmlDepend
void setDependsOn(@Nullable String... dependsOn);
/**
* Return the bean names that this bean depends on.
*/
@Nullable
String[] getDependsOn();
//设置自动装配
void setAutowireCandidate(boolean autowireCandidate);
/**
* Return whether this bean is a candidate for getting autowired into some other bean.
*/
boolean isAutowireCandidate();
/**
* Set whether this bean is a primary autowire candidate.
* <p>If this value is {@code true} for exactly one bean among multiple
* matching candidates, it will serve as a tie-breaker.
* @see #setFallback
*/
void setPrimary(boolean primary);
/**
* Return whether this bean is a primary autowire candidate.
*/
boolean isPrimary();
/**
* Set whether this bean is a fallback autowire candidate.
* <p>If this value is {@code true} for all beans but one among multiple
* matching candidates, the remaining bean will be selected.
* @since 6.2
* @see #setPrimary
*/
void setFallback(boolean fallback);
/**
* Return whether this bean is a fallback autowire candidate.
* @since 6.2
*/
boolean isFallback();
/**
* Specify the factory bean to use, if any.
* This is the name of the bean to call the specified factory method on.
* <p>A factory bean name is only necessary for instance-based factory methods.
* For static factory methods, the method will be derived from the bean class.
* @see #setFactoryMethodName
* @see #setBeanClassName
*/
void setFactoryBeanName(@Nullable String factoryBeanName);
/**
* Return the factory bean name, if any.
* <p>This will be {@code null} for static factory methods which will
* be derived from the bean class instead.
* @see #getFactoryMethodName()
* @see #getBeanClassName()
*/
@Nullable
String getFactoryBeanName();
/**
* Specify a factory method, if any. This method will be invoked with
* constructor arguments, or with no arguments if none are specified.
* The method will be invoked on the specified factory bean, if any,
* or otherwise as a static method on the local bean class.
* @see #setFactoryBeanName
* @see #setBeanClassName
*/
void setFactoryMethodName(@Nullable String factoryMethodName);
/**
* Return a factory method, if any.
* @see #getFactoryBeanName()
* @see #getBeanClassName()
*/
@Nullable
String getFactoryMethodName();
/**
* Return the constructor argument values for this bean.
* <p>The returned instance can be modified during bean factory post-processing.
* @return the ConstructorArgumentValues object (never {@code null})
*/
ConstructorArgumentValues getConstructorArgumentValues();
/**
* Return if there are constructor argument values defined for this bean.
* @since 5.0.2
* @see #getConstructorArgumentValues()
*/
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
/**
* Return the property values to be applied to a new instance of the bean.
* <p>The returned instance can be modified during bean factory post-processing.
* @return the MutablePropertyValues object (never {@code null})
*/
MutablePropertyValues getPropertyValues();
/**
* Return if there are property values defined for this bean.
* @since 5.0.2
* @see #getPropertyValues()
*/
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
/**
* Set the name of the initializer method.
* @since 5.1
*/
void setInitMethodName(@Nullable String initMethodName);
/**
* Return the name of the initializer method.
* @since 5.1
*/
@Nullable
String getInitMethodName();
/**
* Set the name of the destroy method.
* @since 5.1
*/
void setDestroyMethodName(@Nullable String destroyMethodName);
/**
* Return the name of the destroy method.
* @since 5.1
*/
@Nullable
String getDestroyMethodName();
/**
* Set the role hint for this {@code BeanDefinition}. The role hint
* provides the frameworks as well as tools an indication of
* the role and importance of a particular {@code BeanDefinition}.
* @since 5.1
* @see #ROLE_APPLICATION
* @see #ROLE_SUPPORT
* @see #ROLE_INFRASTRUCTURE
*/
void setRole(int role);
/**
* Get the role hint for this {@code BeanDefinition}. The role hint
* provides the frameworks as well as tools an indication of
* the role and importance of a particular {@code BeanDefinition}.
* @see #ROLE_APPLICATION
* @see #ROLE_SUPPORT
* @see #ROLE_INFRASTRUCTURE
*/
int getRole();
/**
* Set a human-readable description of this bean definition.
* @since 5.1
*/
void setDescription(@Nullable String description);
/**
* Return a human-readable description of this bean definition.
*/
@Nullable
String getDescription();
// Read-only attributes
/**
* Return a resolvable type for this bean definition,
* based on the bean class or other specific metadata.
* <p>This is typically fully resolved on a runtime-merged bean definition
* but not necessarily on a configuration-time definition instance.
* @return the resolvable type (potentially {@link ResolvableType#NONE})
* @since 5.2
* @see ConfigurableBeanFactory#getMergedBeanDefinition
*/
ResolvableType getResolvableType();
/**
* Return whether this a <b>Singleton</b>, with a single, shared instance
* returned on all calls.
* @see #SCOPE_SINGLETON
*/
boolean isSingleton();
/**
* Return whether this a <b>Prototype</b>, with an independent instance
* returned for each call.
* @since 3.0
* @see #SCOPE_PROTOTYPE
*/
boolean isPrototype();
/**
* Return whether this bean is "abstract", that is, not meant to be instantiated
* itself but rather just serving as parent for concrete child bean definitions.
*/
boolean isAbstract();
/**
* Return a description of the resource that this bean definition
* came from (for the purpose of showing context in case of errors).
*/
@Nullable
String getResourceDescription();
/**
* Return the originating BeanDefinition, or {@code null} if none.
* <p>Allows for retrieving the decorated bean definition, if any.
* <p>Note that this method returns the immediate originator. Iterate through the
* originator chain to find the original BeanDefinition as defined by the user.
*/
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
2.AbstractBeanDefinition:定义了默认常量与方法,服务BeanDefinition
查看代码
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
//定义默认的常量
public static final String SCOPE_DEFAULT = "";
public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
/**
* Constant that indicates autowiring a constructor.
* @see #setAutowireMode
*/
public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
/**
* Constant that indicates determining an appropriate autowire strategy
* through introspection of the bean class.
* @see #setAutowireMode
* @deprecated as of Spring 3.0: If you are using mixed autowiring strategies,
* use annotation-based autowiring for clearer demarcation of autowiring needs.
*/
@Deprecated
public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
/**
* Constant that indicates no dependency check at all.
* @see #setDependencyCheck
*/
public static final int DEPENDENCY_CHECK_NONE = 0;
/**
* Constant that indicates dependency checking for object references.
* @see #setDependencyCheck
*/
public static final int DEPENDENCY_CHECK_OBJECTS = 1;
/**
* Constant that indicates dependency checking for "simple" properties.
* @see #setDependencyCheck
* @see org.springframework.beans.BeanUtils#isSimpleProperty
*/
public static final int DEPENDENCY_CHECK_SIMPLE = 2;
/**
* Constant that indicates dependency checking for all properties
* (object references as well as "simple" properties).
* @see #setDependencyCheck
*/
public static final int DEPENDENCY_CHECK_ALL = 3;
/**
* The name of an attribute that can be
* {@link org.springframework.core.AttributeAccessor#setAttribute set} on a
* {@link org.springframework.beans.factory.config.BeanDefinition} so that
* bean definitions can indicate one or more preferred constructors. This is
* analogous to {@code @Autowired} annotated constructors on the bean class.
* <p>The attribute value may be a single {@link java.lang.reflect.Constructor}
* reference or an array thereof.
* @since 6.1
* @see org.springframework.beans.factory.annotation.Autowired
* @see org.springframework.beans.factory.support.RootBeanDefinition#getPreferredConstructors()
*/
public static final String PREFERRED_CONSTRUCTORS_ATTRIBUTE = "preferredConstructors";
/**
* The name of an attribute that can be
* {@link org.springframework.core.AttributeAccessor#setAttribute set} on a
* {@link org.springframework.beans.factory.config.BeanDefinition} so that
* bean definitions can indicate the sort order for the targeted bean.
* This is analogous to the {@code @Order} annotation.
* @since 6.1.2
* @see org.springframework.core.annotation.Order
* @see org.springframework.core.Ordered
*/
public static final String ORDER_ATTRIBUTE = "order";
3.包扫描
无非是有两种:
路径+类,通过反射获取到类。
字节码操作技术,直接在字节码中获取元数据,字节码包含这个类的一切信息。
以下代码就是将
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
// 扫描包路径,classpath*:com/xxx/**/*.class 匹配这个包以及子包下的class文件
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
// URL [jar:file:/D:/sourceStudy/spring-framework/spring-study/build/libs/spring-study-6.2.0-SNAPSHOT.jar!/com/ydlclass/bean/Dog.class]
//Spring会将每一个定义的字节码文件加载成为一个Resource资源
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
String filename = resource.getFilename();
if (filename != null && filename.contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
// Ignore CGLIB-generated classes in the classpath
continue;
}
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
try {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
}
else {
if (debugEnabled) {
logger.debug("Ignored because not a concrete top-level class: " + resource);
}
}
}
else {
if (traceEnabled) {
logger.trace("Ignored because not matching any filter: " + resource);
}
}
}
catch (FileNotFoundException ex) {
if (traceEnabled) {
logger.trace("Ignored non-readable " + resource + ": " + ex.getMessage());
}
}
catch (ClassFormatException ex) {
if (shouldIgnoreClassFormatException) {
if (debugEnabled) {
logger.debug("Ignored incompatible class format in " + resource + ": " + ex.getMessage());
}
}
else {
throw new BeanDefinitionStoreException("Incompatible class format in " + resource +
": set system property 'spring.classformat.ignore' to 'true' " +
"if you mean to ignore such files during classpath scanning", ex);
}
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, ex);
}
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return candidates;
}
3.ApplicationContext与BeanFactory区别
ApplicationContext:可以理解成高级容器,具备相对符合的能力。
ListableBeanFactory(具备beanFactoryg管理能力)
HierarchicalBeanFactory 具备分层能力 MessageSource 国籍化能力 ApplicationEventPublisher 事件发送能力public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
...............
..............
4. refresh刷新过程
public void refresh() throws BeansException, IllegalStateException {
this.startupShutdownLock.lock();
try {
// 启动关闭线程,这个线程用来表示启动当前容器使用的线程
// 该成员变量在之前的版本中并不存在,也是为了支持后续的并发实例化bean的情况
this.startupShutdownThread = Thread.currentThread();
// StartupStep是个小工具,用来记录执行流程
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 为当前上下文进行刷新前的准备
prepareRefresh();
// 此处是要初始化一个bean工厂,实时上beanFactory会在上下文构建的就创建了
// 核心的目的是为了提供一种可以进行重复刷新的bean工厂的扩展,虽然我们不用
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 为工厂做一些准备工作,完成一些核心的基础配置
// 这是spring-framework需要做的工作
// 注册几个和环境相关的bean,如:environment、systemProperties、systemEnvironment
prepareBeanFactory(beanFactory);
try {
// 空方法,留给子类去实现,GenericXmlApplicationContext没有进行扩展
// GenericWebApplicationContext进行了扩展,注册了新的作用域,处理了和servlet相关的一些工作
// 此处是spring提供给第三方的框架如spring-mvc等在容器启动前做的配置性工作
postProcessBeanFactory(beanFactory);
// 记录新的步骤,post-process
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 调用所有beanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor的实现类,此时bean没有进行实例化
// 我们可以在此处配置beanFactory,修改beanDefinition
// 此处会处理BeanDefinitionRegistryPostProcessor
// 执行流程会根据priorityOrdered Ordered noOrdered进行排序
// 单独添加了一个listener的探测器,会在bean实例化后判断是否是一个listener,如果是进行注册
invokeBeanFactoryPostProcessors(beanFactory);
// 注册beanPostProcessor,同样会根据priorityOrdered Ordered noOrdered进行排序
registerBeanPostProcessors(beanFactory);
// 结束步骤
beanPostProcess.end();
// 初始化上下文的messageSource
initMessageSource();
// 初始化上下文的多播器
initApplicationEventMulticaster();
// 留出空方法,让子类扩展
// ServletWebServerApplicationContext进行了扩展,创建一个webServer,启动tomcat
onRefresh();
// 注册监听器,此处listenerBean不会被实例化,会议beanName的方式注册
// 还会处理一些早期事件
registerListeners();
// 核心:实例化所有的非懒加载的单例bean
finishBeanFactoryInitialization(beanFactory);
// 完成刷新,发布完成刷新的事件
finishRefresh();
}
// 捕获运行时异常和错误
catch (RuntimeException | Error ex ) {
// 如果日志器支持警告级别,则记录异常信息
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已创建的单例,以避免资源泄露
destroyBeans();
// 重置'active'标志
cancelRefresh(ex);
// 将异常抛给调用者
throw ex;
}
// 无论是否抛出异常,都会执行的代码块,用于清理工作
finally {
contextRefresh.end(); // 结束上下文刷新过程
}
}
// 无论是否抛出异常,都会执行的代码块,用于释放资源
finally {
this.startupShutdownThread = null; // 重置启动/关闭线程
this.startupShutdownLock.unlock(); // 解锁启动/关闭锁
}
}
标签:Return,String,Nullable,spring,基础,see,factory,bean,源码
From: https://www.cnblogs.com/jichenghui/p/18364290