spring容器的整体设计流程如上面的UML图;
顶级类BeanFacoty, 定义了bean的相关规范;
二级类 HierarchicalBeanFactory 和 ListableBeanFactory 对 BeanFacoty 的功能进行了扩展;
ApplicationContext 作为整个容器的中央接口,起着至关重要的作用,为整个容器的启动到配置都提供了功能;
ConfigurableApplicationContext 实现了 ApplicationContext ,所有的资源加载功能都在这个类中进行配置;
后面的类都是具体的子类,使容器功能更加完善;
根据上节源码搭建的测代码,就源码进行调试;
public static void main(String[] args) {
// 获取容器
ApplicationContext ac =new AnnotationConfigApplicationContext(SysConfig.class);
// 获取 bean
SysUser user = (SysUser) ac.getBean("sysUser");
System.out.println(user.toString());
}
进入如下所示构造的方法,首先会调用this()方法,也就是调用构造方法;
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();//初始化构造器
register(componentClasses);
refresh();
}
AnnotationConfigApplicationContext容器构造器如下,重点核心步骤就是 创建 AnnotatedBeanDefinitionReader
,和ClassPathBeanDefinitionScanner
;
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
// 适配器,便捷的注册bean
private final AnnotatedBeanDefinitionReader reader;
//扫描classPath下bean,并注册
private final ClassPathBeanDefinitionScanner scanner;
// 构造器
public AnnotationConfigApplicationContext() {
//开始步骤
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 注入 注解需要的BeanDefinition
this.reader = new AnnotatedBeanDefinitionReader(this);
//结束步骤
createAnnotatedBeanDefReader.end();
//
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
//.......
}
AnnotatedBeanDefinitionReader的方法如下里面就是调用了构造方法,registry 就是 AnnotationConfigApplicationContext ; AnnotationConfigApplicationContext 实现了BeanDefinitionRegistry;
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
进入 构造器先是 getOrCreateEnvironment方法,其是 获取 环境信息;如果BeanDefinitionRegistry 有环境信息就获取,否则返回标准环境信息(JVM的系统变量);
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry instanceof EnvironmentCapable) {
return ((EnvironmentCapable) registry).getEnvironment();// 返回当前registry的环境
}
return new StandardEnvironment();// 返回标准环境
}
看下标准环境属性就是jvm和系统环境变量
public class StandardEnvironment extends AbstractEnvironment {
/**系统环境变量名 */
public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";
/** jvm系统属性名 */
public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";
// 自定义适用于标准环境的属性
@Override
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(
new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));
propertySources.addLast(
new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));
}
}
环境信息是什么?其是一些应用的配置信息,比如一些日志,profile,系统属性等,详细如下;
接口可以看EnvironmentCapable
public interface EnvironmentCapable {
/**
* Return the {@link Environment} associated with this component.
*/
Environment getEnvironment();
}
进入 AnnotatedBeanDefinitionReader 构造方法 ;重点看 ConditionEvaluator 我称为这个为步骤一 和 registerAnnotationConfigProcessors 我称为这个为步骤二;
public class AnnotatedBeanDefinitionReader {
private final BeanDefinitionRegistry registry;// 注册表
// 如果未指定bean名称就会根据驼峰类名生成bean名称
private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
// 监测注解的作用域 ;AnnotationScopeMetadataResolver 实现 ScopeMetadataResolver (函数式的策略接口)
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
// 评估注解
private ConditionEvaluator conditionEvaluator;
//...........
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
// 步骤一
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 步骤二
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
//...........
}
步骤一 : 进入ConditionEvaluator
class ConditionEvaluator {
private final ConditionContextImpl context;
public ConditionEvaluator(@Nullable BeanDefinitionRegistry registry,
@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
//创建实例
this.context = new ConditionContextImpl(registry, environment, resourceLoader);
}
}
进入 ConditionContextImpl可以看到首先就是要初始化 deduceBeanFactory(registry) 方法 , 其次是 deduceResourceLoader(registry) ;
private static class ConditionContextImpl implements ConditionContext {
// registry 知识执行者称为注册表,实际上就是spring容器
@Nullable
private final BeanDefinitionRegistry registry;
// beanFactory
@Nullable
private final ConfigurableListableBeanFactory beanFactory;
// 环境变量
private final Environment environment;
// 资源加载器
private final ResourceLoader resourceLoader;
// 类加载器
@Nullable
private final ClassLoader classLoader;
// 构造器实例化
public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,
@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
this.registry = registry;
//获取 BeanFactory
this.beanFactory = deduceBeanFactory(registry);
// 这边是有环境变量进来
this.environment = (environment != null ? environment : deduceEnvironment(registry));
//这边ResourceLoader资源加载器是空的需要调用方法
this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));
// 类加载器
this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);
}
// ........
}
deduceResourceLoader(registry) 方法 的目的就是 获取 BeanFactory;
private ConfigurableListableBeanFactory deduceBeanFactory(@Nullable BeanDefinitionRegistry source) {
if (source instanceof ConfigurableListableBeanFactory) {
return (ConfigurableListableBeanFactory) source;
}
if (source instanceof ConfigurableApplicationContext) {
//获取 BeanFactory
return (((ConfigurableApplicationContext) source).getBeanFactory());
}
return null;
}
UML图如下
ResourceLoader 本质上还是 BeanDefinitionRegistry 注册表
private ResourceLoader deduceResourceLoader(@Nullable BeanDefinitionRegistry source) {
if (source instanceof ResourceLoader) {
return (ResourceLoader) source;
}
return new DefaultResourceLoader();
}
deduceClassLoader 方法获取的是beanFactory 的类加载器
@Nullable// 类加载器获取的是beanFactory的类加载器
private ClassLoader deduceClassLoader(@Nullable ResourceLoader resourceLoader,
@Nullable ConfigurableListableBeanFactory beanFactory) {
// 这边 resourceLoader 为空
if (resourceLoader != null) {
ClassLoader classLoader = resourceLoader.getClassLoader();
if (classLoader != null) {
return classLoader;
}
}
if (beanFactory != null) {
return beanFactory.getBeanClassLoader();// 获取beanFactory的类加载器
}
return ClassUtils.getDefaultClassLoader();
}
步骤二: registerAnnotationConfigProcessors(this.registry)
registerAnnotationConfigProcessors 注册各种相关的 processors;
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);//注册processors
}
进入registerAnnotationConfigProcessors(registry, null)
其是注册PostProcessor, 而且存放在 map中,主要还是看注入了哪些PostProcessor;
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(// 注册注解相关的processors
BeanDefinitionRegistry registry, @Nullable Object source) {
// 获取底层的beanFactory即 DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
// BeanDefinitionHolder 持有 BeanDefinition 的名称和别名
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 判定是否包含bean
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);//设置 RootBeanDefinition
def.setSource(source);// 设置source
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));// 真正的注册beanDefine
}
// .......... 一堆的判定注册 PostProcessor
return beanDefs;
}
查看下beanDefs 中的内容,应该都是注解需要的PostProcessor
这些PostProcessor 都定义在 AnnotationConfigUtils,主要是 BeanPostProcessor BeanFactoryPostProcessor和AutowireCandidateResolver等;
继续看 registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)
BeanDefinitionHolder 才是真正的 bean 信息的持有者;存放 BeanDefinition,beanName,aliases
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);//设置角色
registry.registerBeanDefinition(beanName, definition);//注册bean
// 反回 BeanDefinitionHolder(存放 BeanDefinition,beanName,aliases)
return new BeanDefinitionHolder(definition, beanName);
}
重点是注册bean : registry.registerBeanDefinition(beanName, definition);
即此时才向 注册表BeanDefinitionRegistry 中注入 RootBeanDefinition,这些都是注解需要的 BeanDefinition;并非 我们的用户 bean;
不知道你们看起来清晰不,回顾一下整个注解注入 BeanDefinition 的流程;
ClassPathBeanDefinitionScanner 是扫描classpath 下 的 bean注入容器;进入构造器
// 加载bean
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
再将纳入构造器里面还是调用了一个构造器;
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
这边 getOrCreateEnvironment(registry) 方法我们之前说明就是为了获取环境如果没有配置则就是获取jvm系统环境;useDefaultFilters 是 个布尔类型,默认就是调用默认的过滤器;
进入三个参数的构造器
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment) {
this(registry, useDefaultFilters, environment,
(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}
registry 是属于 ResourceLoader 的实例,所以不为空;
继续跟踪
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {// 加载bean
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
// true
if (useDefaultFilters) {
registerDefaultFilters();// 设置默认过滤器
}
setEnvironment(environment);// 设置环境
setResourceLoader(resourceLoader);// 设置资源加载器
}
我们主要看下 设置默认过滤器,到底spring是在过滤什么类型的注解;
public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
// 默认的资源路径
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
// 日志
protected final Log logger = LogFactory.getLog(getClass());
// 默认的资源路径
private String resourcePattern = DEFAULT_RESOURCE_PATTERN;
// 包括的注解
private final List<TypeFilter> includeFilters = new LinkedList<>();
// 排除的注解
private final List<TypeFilter> excludeFilters = new LinkedList<>();
// ...........
protected void registerDefaultFilters() {// 为@Component 注解注入过滤器
this.includeFilters.add(new AnnotationTypeFilter(Component.class));// LinkedList 加入 Component 注解
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();// 获取资源加载器
try {// 向过滤器 添加 ManagedBean 注解
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {// 向过滤器 添加 Named 注解
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
// ............
如上源码中includeFilters 和 excludeFilters 都是LinkedList 充当过滤器; includeFilters 表示包含的注解才会被扫描 ,这边就是 @Component , @ ManagedBean, @Named 注解;excludeFilters 表示排除在外的注解,不会被扫描至spring容器;当然这边还无法看见扫描的具体源码,我们后面再看;
我们 搜索Controller 注解,发现类上 也是 @Component 注解, 其余的 @Repository,@Service 本质上也是 @Component 注解;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
// 逻辑层注解
@AliasFor(annotation = Component.class)
String value() default "";
}
回忆一下 ClassPathBeanDefinitionScanner 这个流程所作的事;
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();//初始化构造器
register(componentClasses);
refresh();
}
回到第一个构造器;我们这次看 register(componentClasses); 方法
@Override
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
// 步骤开启
StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
.tag("classes", () -> Arrays.toString(componentClasses));
//注册一个或多个含有@component注解的的类
this.reader.register(componentClasses);
// 步骤结束
registerComponentClass.end();
}
核心方法this.reader.register(componentClasses);
, 就是扫描 含有 @Component注解的类 ,知识追寻这边就是 SysConfig ,因为在配置类上加了 @Configuration 注解,里面也是 @Component注解;
reader 是 AnnotatedBeanDefinitionReader
; 进入方法内部进行循环注入 含有@Component注解的类;
public void register(Class<?>... componentClasses) {
for (Class<?> componentClass : componentClasses) {
registerBean(componentClass);//迭代注入含有@component注解的类
}
}
进入 registerBean(componentClass) 内部;
public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null, null);
}
进入 doRegisterBean(beanClass, null, null, null, null);
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
// 为@Compoent的类创建AnnotatedGenericBeanDefinition,内部是设置bean的过程
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { //1 基于 @Conditional 注解是否跳过加载
return;
}
abd.setInstanceSupplier(supplier);// 创建bean 实例的回调
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);// 2默认单例
abd.setScope(scopeMetadata.getScopeName());// 设置作用域
// 3返回beanName(如果注解上有指定beanName就回返否则根据简单类名作为beanName)
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 4对 AnnotatedGenericBeanDefinition 的一些配置,如懒加载,primary, bean依赖等
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);// 设置primary
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);// 设置懒加载
}
else {
//设置Qualifier限定
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// BeanDefinitionHolder 我们很熟悉,存放 beanName BeanDefinition alias
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 代理
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 5注入BeanDefinition
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
第一个值得说的是this.conditionEvaluator.shouldSkip(abd.getMetadata())
基于 @Conditional 注解是否跳过加载bean;最终会走到shouldSkip 方法,如果元注解中包含 @Conditional true, 否则返回false;
public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {// 基于 @Conditional 注解是否跳过
if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
return false;
}
//......
}
第二个是this.scopeMetadataResolver.resolveScopeMetadata(abd) 默认就是单例模式,可以看接口 ScopeMetadata
;
public class ScopeMetadata {
// 默认单例
private String scopeName = BeanDefinition.SCOPE_SINGLETON;
// 代理模式
private ScopedProxyMode scopedProxyMode = ScopedProxyMode.NO;
//.............
}
内部走的是resolveScopeMetadata(BeanDefinition definition)方法, 目的就是获取元数据信息,如果有指定@scope作用域 则 设置指定值,否则默认单例;
// 获取元数据
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
ScopeMetadata metadata = new ScopeMetadata();
// 默认 singleton MOde 为 NO
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
// 获取 @scope注解的值
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
annDef.getMetadata(), this.scopeAnnotationType);
// @scope属性值不为空
if (attributes != null) {
//获取值
metadata.setScopeName(attributes.getString("value"));
// 获取代理模式
ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
//代理模式等于默认模式
if (proxyMode == ScopedProxyMode.DEFAULT) {
//设置proxyMode为NO
proxyMode = this.defaultProxyMode;
}
// 设置proxyMode
metadata.setScopedProxyMode(proxyMode);
}
}
// 返回元数据信息
return metadata;
}
最终元数据信息如下
第三个是获取bean的名称, 未指定bean名称的情况下,默认简单类名(小写开头驼峰的名字);
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
// 扫描类上的注解,如果有指定beanName 就返回
if (definition instanceof AnnotatedBeanDefinition) {
String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
if (StringUtils.hasText(beanName)) {
// Explicit bean name found.
return beanName;
}
}
// 获取beanName
return buildDefaultBeanName(definition, registry);
}
最后会走到buildDefaultBeanName 方法获取简单类名作为bean的名称
protected String buildDefaultBeanName(BeanDefinition definition) {
String beanClassName = definition.getBeanClassName();
Assert.state(beanClassName != null, "No bean class name set");
String shortClassName = ClassUtils.getShortName(beanClassName);
return Introspector.decapitalize(shortClassName);
}
getShortName 方法就是 对 全类名进行字符串切割
public static String getShortName(String className) {
Assert.hasLength(className, "Class name must not be empty");
int lastDotIndex = className.lastIndexOf(PACKAGE_SEPARATOR);
int nameEndIndex = className.indexOf(CGLIB_CLASS_SEPARATOR);
if (nameEndIndex == -1) {
nameEndIndex = className.length();
}
String shortName = className.substring(lastDotIndex + 1, nameEndIndex);
shortName = shortName.replace(INNER_CLASS_SEPARATOR, PACKAGE_SEPARATOR);
return shortName;
}
第四个是 对 AnnotatedGenericBeanDefinition 的熟悉配置,比如 懒加载@lazy,依赖@dependsOn,首要加载@Primary等;
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
// 设置懒加载
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
// 元注解metadata 就是类上的注解
else if (abd.getMetadata() != metadata) {
lazy = attributesFor(abd.getMetadata(), Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
}
// 设置Primary
if (metadata.isAnnotated(Primary.class.getName())) {
abd.setPrimary(true);
}
// 设置bean依赖
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
abd.setDependsOn(dependsOn.getStringArray("value"));
}
// 设置bean角色
AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null) {
abd.setRole(role.getNumber("value").intValue());
}
//设置描述
AnnotationAttributes description = attributesFor(metadata, Description.class);
if (description != null) {
abd.setDescription(description.getString("value"));
}
}
最后面我们看下 注入bean这个方法调用BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); 从BeanDefinitionHolder 获取 BeanDefinition信息 ,注入到注册表BeanDefinitionRegistry,如果为指定别名就使用bean名称,否则使用别名;
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());// 注入BeanDefinition
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);//指定别名
}
}
}
BeanDefinition 的注册最后走的实现类DefaultListableBeanFactory
中registerBeanDefinition 的方法;
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
// 对bean进行校验
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
// 获从map中取bean
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
// 如果beanDefinition已经存在
if (existingDefinition != null) {
// 不允许 beanDefinition 同名
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
// 角色判定
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
if (logger.isInfoEnabled()) {
// 省略日志
}
}
// 已存在的beanDefinition不相等
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
// 省略日志
}
}
else {
if (logger.isTraceEnabled()) {
// 省略日志
}
}
// 将bean放入map
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
// 监测 factory 的 beanDefinition 已经是否处于创建阶段
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
// 将bean的名称,beanDefinition注入map
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// 将bean的名称,beanDefinition注入map
this.beanDefinitionMap.put(beanName, beanDefinition);
// 将 bean 的名称注入ArrayList
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
// 如果已经存在重新设置所有的BeanDefinition
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);// 重新设置所有的BeanDefinition
}
else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
最终 的BeanDefinition 是放在ConcurrentHashMap中,默认初始容量 256;
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
回顾下注册bean的过程都做了什么
回到刚刚进入构造器的时候我们看refresh() 方法;refresh() 方法有点像电脑重启的意思,spring容器在启动运行的时候会重新加载和扩展一些配置,保证容器的正常运行;
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();//初始化构造器
register(componentClasses);
refresh();
}
进入 refresh方法具体看看
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {// 同步锁
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// 步骤 refresh
// 1准备refresh,里面是AtomicBoolean修饰的标志变量active和 closed
prepareRefresh();
// 2告诉子类refresh bean factory,其实就是获取 bean factory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3为使用容器配置bean factory
prepareBeanFactory(beanFactory);
try {
// 设置 post-processing(后处理)
postProcessBeanFactory(beanFactory);
// 开启步骤 post-process
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 4调用factory processors后处理
invokeBeanFactoryPostProcessors(beanFactory);
// 注册拦截bean 处理器
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 5初始化容器信息,国际化处理
initMessageSource();
// 6初始化容器事件
initApplicationEventMulticaster();
// 初始化特殊的bean(内部没做事情)
onRefresh();
// 7监测并注入监听器
registerListeners();
// 8初始化所有遗留(non-lazy-init)的单例
finishBeanFactoryInitialization(beanFactory);
// 9结束refresh
finishRefresh();
}
catch (BeansException ex) {
// 省略日志
// 摧毁已经创建的单例
destroyBeans();
// 重置标志位
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
resetCommonCaches();// 清空缓存
contextRefresh.end();// 步骤 refresh 结束
}
}
}
1准备refresh,prepareRefresh(); 方法,其主要功能就是设置启动事件,激活标志位并且执行和初始化属性资源
protected void prepareRefresh() {//准备refresh,设置启动事件,激活标志位并且执行和初始化属性资源
// Switch to active.
this.startupDate = System.currentTimeMillis();// 时间戳
this.closed.set(false);// 原子类标志位
this.active.set(true);
// 省略日志
// 初始化 placeholder 属性资源(里面什么都没做)
initPropertySources();//
// 校验系统环境需要的属性
getEnvironment().validateRequiredProperties();
//............
}
这里的 initPropertySources ,什么东西都没有做,但其子类有;
protected void initPropertySources() {
// For subclasses: do nothing by default.
}
getEnvironment().validateRequiredProperties() 就是对系统需要的变量进行校验;
public void validateRequiredProperties() {
MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();// 属性未找到异常
for (String key : this.requiredProperties) {
if (this.getProperty(key) == null) {// 如果系统属性为空,就添加属性
ex.addMissingRequiredProperty(key);
}
}
if (!ex.getMissingRequiredProperties().isEmpty()) {
throw ex;
}
}
**2 获取 bean factory **;
进入obtainFreshBeanFactory 方法,是关于 子类 refresh bean 的操作,本质上是获取BeanFactory ;
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// refresh bean factory
refreshBeanFactory();// 本质上没做什么
return getBeanFactory();// 获取bean
}
我们先看 refreshBeanFactory();该方法在注解配置中本质上未做一些有意义的事情;
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {// cas操作只能refresh一次
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setApplicationStartup(this.getApplicationStartup());// 设置启动
this.beanFactory.setSerializationId(getId());// factory 序列化id
}
其次再看 getBeanFactory(); 方法,这个获取 beanFactory 的方法属于 GenericApplicationContext 容器
// 获取BeanFactory
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
防止忘记,我们再看一下UML图,GenericApplicationContext 容器 是 ConfigurableListableBeanFactory 的子类;
3为使用容器配置bean factory; 主要是对 bean factory 功能的扩展,比如SPEL表达式支持,
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// bean factory 使用 容器的的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// SPEL表达式支持
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// 与 BeanWrapper 有关
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//为容器添加 ApplicationContextAwareProcessor
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 忽略自动装配
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartup.class);
// 为自动装配依赖注入值
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 添加后处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//准备织入
if (!IN_NATIVE_IMAGE && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 注入环境属性bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
我们具体分析下上面相关的源码:
有关SPEL表达式定义和设置可以看 StandardBeanExpressionResolver 解析器;
public class StandardBeanExpressionResolver implements BeanExpressionResolver {
/** Default expression prefix: "#{". */ //前缀
public static final String DEFAULT_EXPRESSION_PREFIX = "#{";
/** Default expression suffix: "}". */ // 后缀
public static final String DEFAULT_EXPRESSION_SUFFIX = "}";
private String expressionPrefix = DEFAULT_EXPRESSION_PREFIX;
private String expressionSuffix = DEFAULT_EXPRESSION_SUFFIX;
// 表达式解析
private ExpressionParser expressionParser;
// 表达式缓存
private final Map<String, Expression> expressionCache = new ConcurrentHashMap<>(256);
// 评估
private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache = new ConcurrentHashMap<>(8);
// ..............
}
有关spel表达式的配置可以看 SpelParserConfiguration
;
public class SpelParserConfiguration {
private static final SpelCompilerMode defaultCompilerMode;
static {
String compilerMode = SpringProperties.getProperty("spring.expression.compiler.mode");
defaultCompilerMode = (compilerMode != null ?
SpelCompilerMode.valueOf(compilerMode.toUpperCase()) : SpelCompilerMode.OFF);
}
private final SpelCompilerMode compilerMode;
@Nullable
private final ClassLoader compilerClassLoader;
private final boolean autoGrowNullReferences;
private final boolean autoGrowCollections;
private final int maximumAutoGrowSize;
//............
}
为自动装配依赖注入值,本质上 是 写入 ConcurrentHashMap中;支持四种@Autowired
注入
BeanFactory
ResourceLoader
ApplicationEventPublisher
ApplicationContext
public void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue) {
Assert.notNull(dependencyType, "Dependency type must not be null");
if (autowiredValue != null) {
if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) {
throw new IllegalArgumentException("Value [" + autowiredValue +
"] does not implement specified dependency type [" + dependencyType.getName() + "]");
}
// 是个 ConcurrentHashMap
this.resolvableDependencies.put(dependencyType, autowiredValue);
}
}
4 调用factory processors后处理;首先会调用getBeanFactoryPostProcessors() 方法 返回一个list,里面存放了大量的 processors bean; 然后通过 invokeBeanFactoryPostProcessors 方法进行后处理;
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 。。。。
}
5初始化容器信息,国际化处理;主要是关于 messageSource 和父 消息源的设置;
protected void initMessageSource() {
// 获取beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
//如果beanFactory中包含 messageSource
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
// 获取messageSource
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// 转为 父消息 HierarchicalMessageSource
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
// 如果父消息源为空则设置
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// 使用DelegatingMessageSource 作为消息源; 空消息
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
// 注册消息源
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isTraceEnabled()) {
logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
}
}
}
6初始化容器事件;如果用户有定义了容器 事件 applicationEventMulticaster则使用 自定义,否则使用默认的SimpleApplicationEventMulticaster 简单事件;
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 包含事件 applicationEventMulticaster则使用
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
//....
}
else {// 如果容器中不包含创建简单事件
SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
// 步骤simpleApplicationEventMulticaster.setApplicationStartup(getApplicationStartup());
this.applicationEventMulticaster = simpleApplicationEventMulticaster;
//注入事件
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
//......
}
}
7监测并注入监听器; 监听器这边没有好的例子可以判定调试,猜测是如果用户有自定义的监听器则使用,否则会加载spring内部默认的监听器;
protected void registerListeners() {// 注入监听器
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
8 初始化所有遗留(non-lazy-init)的单例;当 所有遗留的单例被初始化完成,那么beanFactory 的初始化操作也就结束了;
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//.........
// 暂停使用 temporary ClassLoader
beanFactory.setTempClassLoader(null);
// 冻结 bean definition ,不期望bean发生改变
beanFactory.freezeConfiguration();
//初始化所有遗留(non-lazy-init) 的单例
beanFactory.preInstantiateSingletons();
}
9 结束refresh;源码中显示了初始化生命周期后处理器,这个是结束refresh的重点;
//完成refresh,调用生命周期后处理器
protected void finishRefresh() {
//清除context-level 资源缓存
clearResourceCaches();
// 初始化生命周期后处理器
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// 发布事件给所有的监听器
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
if (!IN_NATIVE_IMAGE) {
LiveBeansView.registerApplicationContext(this);
}
}
看下生命周期接口 原理定义了组件的生命周期;
public interface Lifecycle {
// 开始组件运行
void start();
// 停止组件运行(component)
void stop();
// 监测组件是否正在运行
boolean isRunning();
}
回顾一下 refresh()方法扩展了spring哪些功能;
从整个源码跟踪过程中我们知道了 spring 容器的一个初始化过程,先是初始化构造器 ,在 AnnotatedBeanDefinitionReader 中 为注解的解析bean做准备工作;在ClassPathBeanDefinitionScanner
类中扫描类class path 下的组件类,在这边还定义了默认过滤器,哪些注解类可以通过spring容器注入,哪些类不能被注入,并且配置了环境变量,资源加载器等;其次我们跟踪到了 register 方法,所有外部的bean都是在这边注入,并且还能根据@condition注解是否注入bean; 最后就是 refresh 方法,其是spring的扩展功能,比如SPEL表达式支持,消息处理,事件发布,监听器注入等等;如果感觉收益匪浅,就为作者点赞吧!!
上个小节中知识追寻者使用的是配置类注入方式;本次使用扫描基本包方式看看有何差异;测试代码如下
public static void main(String[] args) {
// 获取容器
ApplicationContext ac =new AnnotationConfigApplicationContext("com.zszxz");
// 获取 bean
SysUser user = (SysUser) ac.getBean("sysUser");
System.out.println(user.toString());
}
进入构造器后如下代码所示,this()调用的构造器是辅助工作(为解析注解配置提供准备)与上小结内容无差异;
refresh()扩展方法也是;所以重点还是看 scan(basePackages)
方法是如何扫描基本包
public AnnotationConfigApplicationContext(String... basePackages) {
// 构造器初始化
this();
// 扫描基本包
scan(basePackages);
// 扩展
refresh();
}
进入scan(basePackages)
方法, 这边的 this.scanner 就是ClassPathBeanDefinitionScanner
,扫描classpath下 bean的作用;
public void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
// 步骤扫描基本包开始
StartupStep scanPackages = this.getApplicationStartup().start("spring.context.base-packages.scan")
.tag("packages", () -> Arrays.toString(basePackages));
// 扫描基本包
this.scanner.scan(basePackages);
// 步骤扫描基本包结束
scanPackages.end();
}
继续跟踪 this.scanner.scan(basePackages); 方法, 又包了一层 doScan(basePackages); 方法
public int scan(String... basePackages) {
// 获取容器中已经注入bean Definition 的个数
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
// 扫描基本包
doScan(basePackages);
// 注解配置后处理器
if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
// 获取当前注入容器bean Definition的个数
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
调试进入 doScan(basePackages); 方法
// 扫描基本包下bean
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
// 遍历基本包
for (String basePackage : basePackages) {
// 获取组件类
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
//获取@Scope注解的值(Bean的作用域)
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
//为Bean设置作用域
candidate.setScope(scopeMetadata.getScopeName());
// 获取bean名称
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
// bean的后处理,配置bean的作用域,懒加载等
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
// 候选bean是否是注解bean
if (candidate instanceof AnnotatedBeanDefinition) {
// bean的后处理,配置bean的作用域,懒加载等
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}// 判定是否是相同的bean
if (checkCandidate(beanName, candidate)) {
;// 创建 BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName)
// 根据作用域设置代理
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
;//加入集合
beanDefinitions.add(definitionHolder)
//向容器注入 bean
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
// 返回 beanDefinition 集合
return beanDefinitions;
}
整个扫描过程看下来 最重要的就是findCandidateComponents(basePackage);
寻找组件方法; 注入bean之前我们说过了,不再赘述;
// 扫描 class path 下的 组件(带有@component注解的类)
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
// 扫描基本包获取组件
return scanCandidateComponents(basePackage);
}
}
继续看 scanCandidateComponents(basePackage);
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
// 补充路径扫描class; packageSearchPath = classpath*:com/zszxz/**/*.class
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
// 资源定位
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
// 资源是个file协议文件
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);// 获取class元数据
if (isCandidateComponent(metadataReader)) {//判定元数据是否在includeFilter过滤器规则范围中
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setSource(resource);
//..........
return candidates;
}
我们这边先不看资源定位,以后再讨论,主要看 isCandidateComponent(metadataReader)
, spring是如何判定bean是否合格;
// 给定的class是否是在过滤器规则内,这个规则定义在ClassPathScanningCandidateComponentProvider 类中我们之前分析过
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
// bean在排除过滤器内返回false
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return false;
}
}
// bean在包含过滤器内,@component注解标注的bean
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
// @Conditional注解相关处理
return isConditionMatch(metadataReader);
}
}
return false;
}
继续看 tf.match(metadataReader, getMetadataReaderFactory()) 匹配规则,这边省略父类规则,和接口匹配规则具体的代码,读者有兴趣自行研究;
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
// 元注解匹配规则
if (matchSelf(metadataReader)) {
return true;
}
ClassMetadata metadata = metadataReader.getClassMetadata();//获取元数据
if (matchClassName(metadata.getClassName())) {// class是否匹配
return true;
}
// 父类匹配规则
if (this.considerInherited) {
// .........
}
// 接口匹配规则
if (this.considerInterfaces) {
// .........
}
return false;
}
我们重点关注的是元注解的匹配规则 matchSelf(metadataReader)
方法;
protected boolean matchSelf(MetadataReader metadataReader) {
// 获取元注解
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
// 判定 元注解中是否包含 @component注解
return metadata.hasAnnotation(this.annotationType.getName()) ||
(this.considerMetaAnnotations && metadata.hasMetaAnnotation(this.annotationType.getName()));
}
到这边我们看看元注解都包括什么内容,其实就是我们的配置类;
我们也看见了this.annotationType.getName() 就是 @Componet 注解;我们最后进入 metadata.hasAnnotation(this.annotationType.getName())
方法再深入跟踪到了 isPresent(Object requiredType, boolean directOnly)
方法 发现这边需要 @Componet ; 而我们 配置上写的是
@Configuration 和 @ComponentScan 注解并不满足条件(虽然@Configuration 中内部有@Componet);如果是**@Componet**我们这边已经通过了;
private boolean isPresent(Object requiredType, boolean directOnly) {
// 遍历元注解
for (MergedAnnotation<?> annotation : this.annotations) {
//获取元注解类型
Class<? extends Annotation> type = annotation.getType();
// 判定 元注解类型是否等于 必须的类型(comPonent)
if (type == requiredType || type.getName().equals(requiredType)) {
return true;
}
}
if (!directOnly) {
for (AnnotationTypeMappings mappings : this.mappings) {
for (int i = 1; i < mappings.size(); i++) {
AnnotationTypeMapping mapping = mappings.get(i);
if (isMappingForType(mapping, requiredType)) {
return true;
}
}
}
}
return false;
}
换另一个或条件 进入metadata.hasMetaAnnotation(this.annotationType.getName())
;
// metaAnnotationName = org.springframework.stereotype.Component
default boolean hasMetaAnnotation(String metaAnnotationName) {
return getAnnotations().get(metaAnnotationName,
MergedAnnotation::isMetaPresent).isPresent();
}
这边一个isPresent() 方法进行判定 get 方法的结果是否存在,若存在返回true, 否则false; 所以最后我们看的还是 get 方法内部的实现
@Override
public <A extends Annotation> MergedAnnotation<A> get(String annotationType,
@Nullable Predicate<? super MergedAnnotation<A>> predicate) {
return get(annotationType, predicate, null);
}
继续跟踪 MergedAnnotation 方法 是否返回有数据;
@Override
public <A extends Annotation> MergedAnnotation<A> get(String annotationType,
@Nullable Predicate<? super MergedAnnotation<A>> predicate,
@Nullable MergedAnnotationSelector<A> selector) {
MergedAnnotation<A> result = find(annotationType, predicate, selector);
return (result != null ? result : MergedAnnotation.missing());
}
经过层层嵌套的查找锁定 find(annotationType, predicate, selector);在这边会循环遍历配置类拥有的注解与给定的注解进行比对,如果成功通过select 选择器返回result;
private <A extends Annotation> MergedAnnotation<A> find(Object requiredType,
@Nullable Predicate<? super MergedAnnotation<A>> predicate,
@Nullable MergedAnnotationSelector<A> selector) {
if (selector == null) {
selector = MergedAnnotationSelectors.nearest();
}
MergedAnnotation<A> result = null;
for (int i = 0; i < this.annotations.length; i++) {
MergedAnnotation<?> root = this.annotations[i];
// mappings 里面就是配置类拥有的注解
AnnotationTypeMappings mappings = this.mappings[i];
for (int mappingIndex = 0; mappingIndex < mappings.size(); mappingIndex++) {
AnnotationTypeMapping mapping = mappings.get(mappingIndex);
// 遍历判定mappings 中是否包含必须类型
if (!isMappingForType(mapping, requiredType)) {
continue;
}// candidate 就是我们的配置类
MergedAnnotation<A> candidate = (mappingIndex == 0 ? (MergedAnnotation<A>) root :
TypeMappedAnnotation.createIfPossible(mapping, root, IntrospectionFailureLogger.INFO));
if (candidate != null && (predicate == null || predicate.test(candidate))) {
if (selector.isBestCandidate(candidate)) {
return candidate;
}
// 返回结果
result = (result != null ? selector.select(result, candidate) : candidate);
}
}
}
return result;
}
我们最后看下遍历的结果result;
回顾一下整个扫描基本包方式spring容器的初始化流程
经过上面的源码分析我们已经知道了spring容器的整个初始化过程,但我们肯定还是对每个容器的功能并不是很懂,所以还是需要分析一下重要的spring容器上下文;
BeaFactory 的作用就是 获取bean, 判定单例原型,获取bean的提供者等提供一系列的规范;
public interface BeanFactory {
// beanFactory的前缀 用于取消引用和区分bean,返回的是factory;
String FACTORY_BEAN_PREFIX = "&";
// 获取 bean
Object getBean(String name) throws BeansException;
// 获取 bean
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
// 获取 bean
Object getBean(String name, Object... args) throws BeansException;
// 获取 bean
<T> T getBean(Class<T> requiredType) throws BeansException;
// 获取 bean
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
// 获取 bean 的 provider
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
// 获取 bean 的 provider
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
// 是否包含 bean
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);
}
HierarchicalBeanFactory 的主要功能就是 支持获取 父类 的 BeanFactory;
public interface HierarchicalBeanFactory extends BeanFactory {
// 获取 父 BeanFactory
@Nullable
BeanFactory getParentBeanFactory();
// 是否包含 local bean factory
boolean containsLocalBean(String name);
}
ListableBeanFactory 对 BeanFactory 功能做了扩展,能够返回更多bean的信息;
public interface ListableBeanFactory extends BeanFactory {
// bean factory 中是否包含 bean definition
boolean containsBeanDefinition(String beanName);
// 返回 bean factory 中 beans defined 的数量
int getBeanDefinitionCount();
// 返回 bean factory 中 所有 beans defined 的名称
String[] getBeanDefinitionNames();
// 通过给定的类型返沪适配的 bean 的名称
String[] getBeanNamesForType(ResolvableType type);
// 通过给定的类型(包括子类)返沪适配的 bean 的名称,
String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);
// 通过给定的类型(包括子类)返沪适配的 bean 的名称
String[] getBeanNamesForType(@Nullable Class<?> type);
// 通过给定的类型(包括子类)返沪适配的 bean 的名称;
String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
// 通过类型返回 bean 的名称和实例
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
// 通过类型返回 bean 的名称和实例
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
// 返回所有的bean 名称 通过 注解类型
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
// 通过注解类型返回所有 bean 的名称 和实例
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
// 从指定的bean中返回 指定类型的注解
@Nullable
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
}
ApplicationContext 应用上下文作为中央接口,为应用程序提供配置,起着承上启下的作用;
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
// 返回上下文id
@Nullable
String getId();
// 返回部署的应用程序的名称,或者默认为空字符串
String getApplicationName();
// 返回上下文的显示名称
String getDisplayName();
// 返回上下文第一次加载的时间戳
long getStartupDate();
// 返回父上下文
@Nullable
ApplicationContext getParent();
// 获取 AutowireCapableBeanFactory
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
ConfigurableApplicationContext 实现了 ApplicationContext , 添加了资源加载配置功能, 比如环境变量的定义,加载class path 路径下的资源, jvm关闭后容器的摧毁都在这个上下文中定义;
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {
//应用上下文配置时,这些符号用于分割多个配置路径
String CONFIG_LOCATION_DELIMITERS = ",; \t\n";
//BeanFactory中,ConversionService类所对应的bean的名字,如果未提供使用默认规则
String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
// LoadTimeWeaver bean 在 factory 中的名字
String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
//Environment bean 在factory中的名字
String ENVIRONMENT_BEAN_NAME = "environment";
// 系统属性 bean 在factory中的名字
String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";
// 系统环境 bean 在 factory 中的名字
String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";
// 启动步骤在factory中的名字
String APPLICATION_STARTUP_BEAN_NAME = "applicationStartup";
// 上下文关闭钩子名称
String SHUTDOWN_HOOK_THREAD_NAME = "SpringContextShutdownHook";
// 设置上下文id
void setId(String id);
// 设置父上下文
void setParent(@Nullable ApplicationContext parent);
// 为上下文设置环境
void setEnvironment(ConfigurableEnvironment environment);
// 返回上下文的环境
@Override
ConfigurableEnvironment getEnvironment();
// 为上下文设置启动步骤
void setApplicationStartup(ApplicationStartup applicationStartup);
// 获取上下文启动步骤
ApplicationStartup getApplicationStartup();
// 添加后处理器,在reresh的时候调用
void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);
// 添加新的应用监听器,会唤起容器事件
void addApplicationListener(ApplicationListener<?> listener);
// 指定类加载器加载 class path 下的资源和 bean
void setClassLoader(ClassLoader classLoader);
// 为上下文注册protocol resolver
void addProtocolResolver(ProtocolResolver resolver);
// 加载资源配置,比如 基于java的基本配置,xml配置,属性文件等
void refresh() throws BeansException, IllegalStateException;
// 向 jvm 注入 钩子,当jvm关闭时,摧毁上下文;
void registerShutdownHook();
// 关闭应用上下文
@Override
void close();
// 判定上下文是否激活
boolean isActive();
// 返回 bean factory
ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}
BeanDefinitionRegistry 是一个注册表,里面注册了 BeanDefinition;AnnotationConfigApplicationContext(spring容器) 就是 BeanDefinitionRegistry 的子类;BeanDefinition 是 描述bean实例的信息;
//BeanDefinitionRegistry(bean的注册表含有definitions)
public interface BeanDefinitionRegistry extends AliasRegistry {
//向注册表(Register)中注册新的definition
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
//从BeanDefinition中移除bean
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
//返回给定bean的BeanDefinition
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
//判定registry中是否含有给定的bean
boolean containsBeanDefinition(String beanName);
// 返回registry中bean的名称
String[] getBeanDefinitionNames();
//返回registry中bean的数量
int getBeanDefinitionCount();
//判定bean的名称是否已经被使用
boolean isBeanNameInUse(String beanName);
}
BeanDefinition 包含 bean 的实例信息,比如bean的作用域,初始化方法,构造参数,摧毁方法,懒加载,工厂方法等等;
// BeanDefinition 包含bean实例的信息
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
//单例
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
//原型
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
//角色-用户自己定义的bean
int ROLE_APPLICATION = 0;
//角色-配置类较大的bean
int ROLE_SUPPORT = 1;
// 角色-内部工作使用的bean
int ROLE_INFRASTRUCTURE = 2;
// Modifiable attributes
// 设置父的definition名称
void setParentName(@Nullable String parentName);
//获取父bean definition 名称
@Nullable
String getParentName();
// 设置指定的 bean definition 名称
void setBeanClassName(@Nullable String beanClassName);
//获取 bean definition 名称
@Nullable
String getBeanClassName();
// 设置作用域
void setScope(@Nullable String scope);
// 获取作用域
@Nullable
String getScope();
// 设置bean 是否懒加载
void setLazyInit(boolean lazyInit);
// 判定bean 是否懒加载
boolean isLazyInit();
// 设置 bean 的依赖
void setDependsOn(@Nullable String... dependsOn);
// 获取bean依赖的bean名称
@Nullable
String[] getDependsOn();
// 设置自动注入候选
void setAutowireCandidate(boolean autowireCandidate);
// 判定自动注入候选
boolean isAutowireCandidate();
// 设置 首要的bean
void setPrimary(boolean primary);
// 判定是否是首要的bean
boolean isPrimary();
// 指定bean 工厂
void setFactoryBeanName(@Nullable String factoryBeanName);
// 返回 bean 工厂名称
@Nullable
String getFactoryBeanName();
// 设定工厂方法
void setFactoryMethodName(@Nullable String factoryMethodName);
// 返回工厂方法
@Nullable
String getFactoryMethodName();
// 返回bean 的构造器参数
ConstructorArgumentValues getConstructorArgumentValues();
// 判定构造器参数是否为空
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
// 返回应用于实例中bean的属性值
MutablePropertyValues getPropertyValues();
// 判定bean中定义的属性值
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
// 设置初始化方法
void setInitMethodName(@Nullable String initMethodName);
// 返回初始化方法
@Nullable
String getInitMethodName();
// 设置摧毁方法
void setDestroyMethodName(@Nullable String destroyMethodName);
// 获取摧毁的方法
@Nullable
String getDestroyMethodName();
// 设置角色
void setRole(int role);
// 获取角色
int getRole();
// 设置bean definition 的描述
void setDescription(@Nullable String description);
// 返回bean definition 的描述
@Nullable
String getDescription();
// Read-only attributes
// 返回bean 的解析类型
ResolvableType getResolvableType();
/判定bean是否 单例
boolean isSingleton();/
// 判定bean是否 原型
boolean isPrototype();
// 判定bean是否抽象
boolean isAbstract();
// 返回bean资源的描述
@Nullable
String getResourceDescription();
// 返回原始bean的 BeanDefinition
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
再看UML图AbstractBeanDefinition 是 继承了 BeanDefinition;
现在是不是有一种感觉BeanDefinitionRegistry 就是一个容器,里面注入了大量的bean的信息BeanDefinition ;
步骤属于 spring-core 包,是用于记录spring容器的运行步骤;
public interface ApplicationStartup {// spring容器启动后标记步骤
ApplicationStartup DEFAULT = new DefaultApplicationStartup();
StartupStep start(String name);//开始执行的步骤
}
ApplicationStartup 的实现类是DefaultApplicationStartup;
class DefaultApplicationStartup implements ApplicationStartup {
@Override
public DefaultStartupStep start(String name) {
return new DefaultStartupStep();
}
static class DefaultStartupStep implements StartupStep {
// 初始的记录为false
boolean recorded = false;
// 默认标签
private final DefaultTags TAGS = new DefaultTags();
@Override
public String getName() {
return "default";
}
// 获取当前步骤id
@Override
public long getId() {
return 0L;
}
// 获取父步骤id
@Override
public Long getParentId() {
return null;
}
// 获取标签
@Override
public Tags tags() {
return this.TAGS;
@Override
public StartupStep tag(String key, String value) {
if (this.recorded) {
throw new IllegalArgumentException();
}
return this;
}
@Override
public StartupStep tag(String key, Supplier<String> value) {
if (this.recorded) {
throw new IllegalArgumentException();
}
return this;
}
// 结束后记录为true
@Override
public void end() {
this.recorded = true;
}
// 标签是本质一个迭代器用于存放 StartupStep.Tag具体可以看接口StartupStep
static class DefaultTags implements StartupStep.Tags {
@Override
public Iterator<StartupStep.Tag> iterator() {
return Collections.emptyIterator();
}
}
}
}
DefaultApplicationStartup 内部有个静态类DefaultStartupStep实现 StartupStep接口,定义了具体步骤的规范
public interface StartupStep {
// 返回步骤名称
String getName();
// 唯一的步骤id
long getId();
// 父步骤id
@Nullable
Long getParentId();
// 对步骤添加标签
StartupStep tag(String key, String value);
// 对步骤添加标签
StartupStep tag(String key, Supplier<String> value);
// 返回步骤的标签集合
Tags tags();
// 记录的是步骤的状态
void end();
// 可变集合
interface Tags extends Iterable<Tag> {
}
//key和value 关联 步骤的元数据
interface Tag {
// 返回表情 名称 即key
String getKey();
// 返回 value
String getValue();
}
}
实现类如下: