首先创建一个基础的环境,注意这几个放在一个包里面
1,启动环境
@Configuration
@ComponentScan(basePackages = "com.learn.day2")
@Import({Bean2.class})
@ImportResource
public class Day2Test {
/**
* 查看Spring是如何注入的
* @param args
*/
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(Day2Test.class);
Bean1 bean = context.getBean(Bean1.class);
System.out.println(bean);
}
}
2,带注解的Bean1
@Component
public class Bean1 {
}
3,不带注解的Bean2
public class Bean2 {
}
4,带注解的Bean3
@Component
public class Bean3 {
@Autowired
Bean2 bean2;
}
启动后首先进入到AnnotationConfigApplicationContext->this()初始化方法,这个先略过。。
public AnnotationConfigApplicationContext(Class>... annotatedClasses) {
this();
System.out.println("AnnotationConfigApplicationContext:调用this()方法");
register(annotatedClasses);
refresh();
}
重点研究register()方法:最终调用 AnnotatedBeanDefinitionReader 的doRegisterBean()方法,此方法将配置类添加到BeanFactory的beanDefinitionMap中去
//BeanDefinitionHolder 相当于一个map 通过name 获取BD
//如果是内部类 跳过
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//设置BD属性
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//自定义BD属性
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
//相当于一个map 通过name 获取BD
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
//注册所有的别名,并调用registerBeanDefinition 注册BD
// 使用baen名称注册
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 注册所有bean的别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
这个方法判断当前容器是否有这个BD,如果有可覆盖就覆盖。
没有就判断当前容器初始化阶段,如果是创建阶段就直接直接放入BD
/** bean 定义的集合类 key是当前的beanName */
private final Map beanDefinitionMap = new ConcurrentHashMap<>(256);
//如果已经开始创建了 就直接加入
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
/**
* 全局的map 要加锁
*/
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
此时看下AnnotationConfigApplicationContext中BeanFactory已经创建起来了,并且BeanDefinitionMap中已经创建了一些BD,包含我们的配置类。
register()方法执行之前
register()方法执行之后
再往下就是经典的refresh方法:让我们回到AnnotationConfigApplicationContext的refresh方法
准备工作,记录下容器的启动时间、标记“已启动”状态、以及监听等
protected void prepareRefresh() {
// 将 active 属性设置为 true,closed 属性设置为 false,它们都是 AtomicBoolean 类型
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// 实现初始化属性资源文件
initPropertySources();
// 校验 xml 配置文件
getEnvironment().validateRequiredProperties();
// 保存刷新容器之前的监听
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
this.earlyApplicationEvents = new LinkedHashSet<>();
}
获取beanFactory 已经有了不是吗 略。。
prepareBeanFactory()加载classloader addBeanPostProcessor等 略。。
postProcessBeanFactory()略。。
invokeBeanFactoryPostProcessors()解析包 bean的操作在这里
一直往下面追踪到
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
processConfigBeanDefinitions(registry);
//到这一步才是真正开始去扫描bean的操作,此时注册器,资源读取器等已经准备好
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set candidates = new LinkedHashSet<>(configCandidates);
Set alreadyParsed = new HashSet<>(configCandidates.size());
do {
//开始解析
parser.parse(candidates);
parser.validate();
try {
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
SourceClass sourceClass = asSourceClass(configClass);
do {
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
Set scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
//添加解析器 过滤条件等
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
Class extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
return scanner.doScan(StringUtils.toStringArray(basePackages));
Set beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
Set candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
Set candidates = new LinkedHashSet<>();
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
}
.....
}
}
}
返回扫描到的了我们的三个Bean,并返回处理
接下来回到doScan()返回BD集合
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
这个方法是不是很熟悉?这个就是注册注解类的方法,讲BD添加到beanDefinitionMap中去
// 使用baen名称注册
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 注册所有bean的别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
好的,到这里我们的三个Bean,一个配置Bean都已经注册完了
接下来再回到doScan()方法,抛一个引子后面会说到
// 处理@Import注解 注册制定的类 springboot很重要的注解
processImports(configClass, sourceClass, getImports(sourceClass), true);
// 处理@ImportResource 注解 注册资源文件 还记得Mybatise吗
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
现在整个项目中的可用BD都已经拿到了,然后我们继续经典的Refresh()方法
registerBeanPostProcessors(beanFactory); //添加几个处理器..
initMessageSource(); //国际化
initApplicationEventMulticaster();//初始化当前 ApplicationContext 的事件广播器
onRefresh();//初始化一些特殊的Bean,有需求就实现它
registerListeners();//注册监听器
finishBeanFactoryInitialization(beanFactory);//初始化所有单例Bean
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
....
}
}
else {
getBean(beanName);
}
这个方法主要做了两件事。第一件事是在创建Bean前给InstantiationAwareBeanPostProcess机会处理创建Bean返回;第二件事是调用doCreateBean创建Bean。
try {
// 初始化之前的通知 可以返回一个代理Bean
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//开始创建实例对象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
调用Bean的构造函数创建Bean,这时候并没有初始化Bean;
// 实例化Bean the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//调用Bean的构造函数创建Bean,这时候并没有初始化Bean;
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
实例化Bean的所有字段
// 就是实例化Bean的字段
Object exposedObject = bean;
try {
//其中populateBean中会自动注入带有@Autowired,@Resource等注解的Bean
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);//实例化Bean
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
至此,一个Bean对象就创建完成了