1.Spring 5下载
2.进入Spring Framework
3.进入Spring5的github 按照下面步骤
然后根据地址下载需要的版本

Spring的在线文档;
离线文档:
2.Spring学习的核心内容:
1.Spring核心学习内容IOC,AOP,jdbcTemplate,声明式事务
2.IOC:控制反转,可以管理java对象
3.AOP:切面编程
4.JDBCTemplate:是spring提供一套访问数据库的技术,应用性强,相对好理解
5.声明式事务:基于IOC/AOP实现事务管理,理解需要花时间
6.IOC.AOP是重点同时也是难点
Spring几个重要概念:
1.Spring可以整合其他的框架(Spring是管理框架的框架)
2.Spring有两个核心的概念:IOC和AOP
3.传统的开发模式:
程序------>环境//程序读取环境配置,然后自己创建对象
IOC的开发模式:容器--------->程序//容器创建好对象,程序直接使用
1.Spring根据配置文件xml/注解,创建对象,并放入到容器(ConcurrentHashMap)中,并且可以完成对象之间的依赖。
2.当需要使用某个对象实例的时候,就直接从容器中获取即可。
3.程序员可以更加关注如何使用对象完成相应的业务。
4.DI依赖注入,可以理解成事IOC的另外叫法。
5.Spring最大的价值,通过配置,给程序提供需要使用的web层对象,这个是核心价值所在,也是IOC的具体体现,实现解耦。
3.手写简易SpringFrame框架:
实现一下内容:
1.手写模拟Spring容器启动过程底层实现
2.手写模拟Spring解析配置类底层实现
3.手写模拟Spring扫描Bean过程底层实现
4.手写模拟Bean生命周期创建过程底层实现
5.手写模拟Bean生命周期依赖注入过程底层实现
6.手写模拟Bean生命周期Aware回调过程底层实现
7.手写模拟Bean生命周期初始化过程底层实现
8.手写模拟BeanDefinition生成过程底层实现
9.手写模拟@Component,@ComponentScan
10.手写模拟@Autowired,@PostConstruct
11.手写模拟BeanPostProcessor后置处理底层实现
12.手写模拟Spring AOP过程底层实现
13.手写模拟Pointcut,Advisor,Advice底层实现

代码仓库:https://gitee.com/CHEN--YUQIAO/spring-frame 参考学习
4.Spring源码中核心组件的使用与解析
4.1BeanDefinition
BeanDefinition是非常非常核心的一个概念,一个BeanDefinition表示一个Bean定义,Spring会根据BeanDefinition来创建具体的Bean对象。
BeanDefinition中常用的属性:
- beanClass,表示Bean的类型
- scope,表示Bean的作用域,比如单例或多例
- LazyInit:表示Bean是不是懒加载的
- initMethodName:表示Bean初始化时要执行的方法
- destoryMethodName:表示Bean销毁时要执行的方法
当使用@Bean,@Component等方式定义Bean时,Spring底层就会解析这些标签和注解生成对应的BeanDefinition对象。(声明式创建)
也可以通过编程式定义和注册BeanDefinition:
java
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(DeviceService.class);
BeanDefinition definition=new AnnotatedGenericBeanDefinition(DeviceService.class);
definition.setScope("prototype");
definition.setLazyInit(false);
definition.setInitMethodName("a");
applicationContext.registerBeanDefinition("deviceService",definition);
5.BeanDefinition扫描过程源码解析
java
package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.annotation.AliasFor;
import org.springframework.core.type.filter.TypeFilter;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("value")
String[] basePackages() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Class<?>[] basePackageClasses() default {};
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
boolean useDefaultFilters() default true;
Filter[] includeFilters() default {};
Filter[] excludeFilters() default {};
boolean lazyInit() default false;
@Retention(RetentionPolicy.RUNTIME)
@Target({})
@interface Filter {
FilterType type() default FilterType.ANNOTATION;
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
String[] pattern() default {};
}
}




java/* * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.context.annotation; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.config.BeanDefinitionHolder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanNameGenerator; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.env.Environment; import org.springframework.core.io.ResourceLoader; import org.springframework.core.type.filter.AbstractTypeHierarchyTraversingFilter; import org.springframework.core.type.filter.TypeFilter; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; /** * Parser for the @{@link ComponentScan} annotation. * * @author Chris Beams * @author Juergen Hoeller * @author Sam Brannen * @since 3.1 * @see ClassPathBeanDefinitionScanner#scan(String...) * @see ComponentScanBeanDefinitionParser */ class ComponentScanAnnotationParser { private final Environment environment; private final ResourceLoader resourceLoader; private final BeanNameGenerator beanNameGenerator; private final BeanDefinitionRegistry registry; public ComponentScanAnnotationParser(Environment environment, ResourceLoader resourceLoader, BeanNameGenerator beanNameGenerator, BeanDefinitionRegistry registry) { this.environment = environment; this.resourceLoader = resourceLoader; this.beanNameGenerator = beanNameGenerator; this.registry = registry; } public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, String declaringClass) { 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)); ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy"); if (scopedProxyMode != ScopedProxyMode.DEFAULT) { scanner.setScopedProxyMode(scopedProxyMode); } else { Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver"); scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass)); } scanner.setResourcePattern(componentScan.getString("resourcePattern")); for (AnnotationAttributes includeFilterAttributes : componentScan.getAnnotationArray("includeFilters")) { List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(includeFilterAttributes, this.environment, this.resourceLoader, this.registry); for (TypeFilter typeFilter : typeFilters) { scanner.addIncludeFilter(typeFilter); } } for (AnnotationAttributes excludeFilterAttributes : componentScan.getAnnotationArray("excludeFilters")) { List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(excludeFilterAttributes, this.environment, this.resourceLoader, this.registry); for (TypeFilter typeFilter : typeFilters) { scanner.addExcludeFilter(typeFilter); } } boolean lazyInit = componentScan.getBoolean("lazyInit"); if (lazyInit) { scanner.getBeanDefinitionDefaults().setLazyInit(true); } Set<String> basePackages = new LinkedHashSet<>(); String[] basePackagesArray = componentScan.getStringArray("basePackages"); for (String pkg : basePackagesArray) { String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg), ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); Collections.addAll(basePackages, tokenized); } for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) { basePackages.add(ClassUtils.getPackageName(clazz)); } if (basePackages.isEmpty()) { basePackages.add(ClassUtils.getPackageName(declaringClass)); } scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) { @Override protected boolean matchClassName(String className) { return declaringClass.equals(className); } }); return scanner.doScan(StringUtils.toStringArray(basePackages)); } }
ComponentScanAnnotationParser这个类是CompanentScan注解的解析器,用来构建并给scan扫描对象赋值,做扫描前的准备!!
javaprotected 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) { //扫描basePackage中的所有类,并注册到BeanDefinitionRegistry中 Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { //获取bean的scope ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); //生成beanName String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); //给BeanDefinition对象中的属性赋默认值 if (candidate instanceof AbstractBeanDefinition) { postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } //解析@Lazy,@Primary,@Fallback,@DependsOn,@Role,@Description等注解并赋值给BeanDefinition对应的属性 if (candidate instanceof AnnotatedBeanDefinition) { AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } //检查beanName是否已存在 if (checkCandidate(beanName, candidate)) { //BeanDefinitionHolder的作用实在BeanDefinition的基础上 添加了beanName BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); //如果设置了ScopedProxyMode,则会生成一个新的BeanDefinition,类型为ScopedProxyFactoryBean definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); //注册beanDefinition registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }
接下来进入第一个方法,看看是如何实现扫描,获得候选BeanDefinition的:
javapublic Set<BeanDefinition> findCandidateComponents(String basePackage) { if (this.componentsIndex != null && indexSupportsIncludeFilters()) { return addCandidateComponentsFromIndex(this.componentsIndex, basePackage); } else { return scanCandidateComponents(basePackage); } }
构建扫描路径 → 查找所有类资源 → 读取类元数据 → 双重过滤(规则匹配 + 类合法性) → 生成 Bean 定义。
javaprivate Set<BeanDefinition> scanCandidateComponents(String basePackage) { Set<BeanDefinition> 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); } try { //利用ASM技术解析每个.class文件得到类的各种信息(类的元数据信息) MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource); //利用exludeFileters和includeFilters判断当前class是否为bean if (isCandidateComponent(metadataReader)) { ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setSource(resource); //不能是接口或抽象类,如果是抽象类,但是有@Lookup注解的方法则通过 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 (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; }
进入第一重过滤的方法如下:
javaprotected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { for (TypeFilter tf : this.excludeFilters) { if (tf.match(metadataReader, getMetadataReaderFactory())) { return false; } } for (TypeFilter tf : this.includeFilters) { if (tf.match(metadataReader, getMetadataReaderFactory())) { return isConditionMatch(metadataReader); } } return false; }
第二重过滤方法如下:
此时,对 findCandidateComponents()方法的剖析就已经完成!!
接下来继续看扫描中的
checkCandidate()方法 即检查beanName是否已经存在
到这里doscan()方法的逻辑就理清楚了!
接下来,总结一下:扫描的入口------> 容器调用refresh()方法
接着会调用到
ConfigurationClassParser类中的
doProcessConfigurationClass()方法
调用parse()回到上面分析过得,创建一个scanner对象,然后再调用doscan()实现扫描!!