spring版本:5.1.9
boot版本:2.1.7
因为spring的refresh()很复杂,为了简化只关注自己注解的解析过程。
我也是经过长时间的源码阅读和跟踪源码的方法,请细心对照源码阅读。
…省略号:忽略次要代码
Application 入口
@SpringBootApplication()
@ComponentScan(includeFilters = @ComponentScan.Filter())
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
EmployeeController .java
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private EmployeeService employeeService;
@GetMapping("/list")
public List<Employee> list() {
return employeeService.list();
}
}
EmployeeServiceImpl .java
@Service
public class EmployeeServiceImpl implements EmployeeService {
public List<Employee> list() {
List<Employee> list = new ArrayList<Employee>();
for (int i = 0; i < 5; i++) {
Employee e = new Employee(i + 1, "name" + i, 20 + i, "深圳" + i, null);
list.add(e);
}
return list;
}
}
Employee.java
public class Employee {
private int id;
private String name;
private int age;
private String address;
private String description;
...
}
下面是spring如何注册EmployeeController 和EmployeeServiceImpl 两个类的过程:
从上到下的依次调用过程,请大家查考源码
先看下时序图,在参考下面的源码解析
SpringApplication:
public ConfigurableApplicationContext run(String... args) {
...
ConfigurableApplicationContext context = null;
context = createApplicationContext(); //创建context 的环境
refreshContext(context);//调用下面的refresh()
...
}
AbstractApplicationContext
public void refresh() throws BeansException, IllegalStateException {
...
// 获取内部的beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//调用在上下文中注册为Bean的工厂处理器。
invokeBeanFactoryPostProcessors(beanFactory);//往下走
...
}
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
...
}
PostProcessorRegistrationDelegate
//这个方法有非常多的处理,重点关注invokeBeanDefinitionRegistryPostProcessors()
public static void invokeBeanFactoryPostProcessors( beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
...
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
...
}
private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);//往下走
}
}
ConfigurationClassPostProcessor
private ConfigurationClassBeanDefinitionReader reader;
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
...
processConfigBeanDefinitions(registry);
}
//这个方法也有很多处理,重点关注parser(),loadBeanDefinitions()
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
...
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
do {
parser.parse(candidates);//往下走 1.ConfigurationClassParser
this.reader.loadBeanDefinitions(configClasses);//往下走2.ConfigurationClassBeanDefinitionReader
}while (!candidates.isEmpty());
...
}
1.ConfigurationClassParser 分支
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
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());
}
}
}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
SourceClass sourceClass = asSourceClass(configClass);
do {
sourceClass = doProcessConfigurationClass(configClass, sourceClass);//往下走
}
while (sourceClass != null);
}
private final ComponentScanAnnotationParser componentScanParser;
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)throws IOException {
...
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
for (AnnotationAttributes componentScan : componentScans) {
//通过@ComponentScan扫描,解析注解
Set<BeanDefinitionHolder> scannedBeanDefinitions =
componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());//往下走
}
...
}
ComponentScanAnnotationParser
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
...
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
return scanner.doScan(StringUtils.toStringArray(basePackages));//往下走
}
ClassPathBeanDefinitionScanner
private final BeanDefinitionRegistry registry;//这个注册器非常重要,所有解析的注解都放在这个对象中
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
...
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);//重点看ClassPathScanningCandidateComponentProvider
for (BeanDefinition candidate : candidates) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
//这里通过代理解析出注解的定义
definitionHolder =AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, registry);//往下走
}
...
}
protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);//往下走
}
ClassPathScanningCandidateComponentProvider
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
return scanCandidateComponents(basePackage);
}
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
//扫描路径:例如 com.test.controller
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
//创建出扫描的路径下的所有对应的注解的class
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
for (Resource resource : resources) {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
candidates.add(sbd);
}
return candidates;
}
BeanDefinitionReaderUtils
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());//往下走
}
GenericApplicationContext
private final DefaultListableBeanFactory beanFactory;//这个就是传说中的beanFactory
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
DefaultListableBeanFactory
/** 这个Map就是保存的传说中的bean对象,key是bean名称 */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/** 这个List保存的是排好序的bean的名称 */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
...
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
this.beanDefinitionMap.put(beanName, beanDefinition);
}else {
//重点
if (hasBeanCreationStarted()) {
synchronized (this.beanDefinitionMap) {
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 {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
}
...
}
华丽的---------------------------------------------------------------分割线
2.ConfigurationClassBeanDefinitionReader分支
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
...
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
private void loadBeanDefinitionsFromImportedResources(
Map<String, Class<? extends BeanDefinitionReader>> importedResources) {
importedResources.forEach((resource, readerClass) -> {
...
BeanDefinitionReader reader = readerInstanceCache.get(readerClass);
if(reader==null){
reader = readerClass.getConstructor(BeanDefinitionRegistry.class).newInstance(this.registry);
}
reader.loadBeanDefinitions(resource);
});
}
AbstractBeanDefinitionReader
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
return loadBeanDefinitions(location, null);
}
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = getResourceLoader();
...
if (resourceLoader instanceof ResourcePatternResolver) {
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
int count = loadBeanDefinitions(resources);//往下走
}else {
Resource resource = resourceLoader.getResource(location);
int count = loadBeanDefinitions(resource);//往下走
}
}
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
for (Resource resource : resources) {
//这里有个实现类实现
//1.XmlBeanDefinitionReader
//2.GroovyBeanDefinitionReader
//3.PropertiesBeanDefinitionReader
count += loadBeanDefinitions(resource);
}
}
1.XmlBeanDefinitionReader,xml配置的方式解析
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
...
InputSource inputSource = new InputSource(inputStream);
...
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
Document doc = doLoadDocument(inputSource, resource);
int count = registerBeanDefinitions(doc, resource);
}
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));//往下走
return getRegistry().getBeanDefinitionCount() - countBefore;
}
DefaultBeanDefinitionDocumentReader
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
doRegisterBeanDefinitions(doc.getDocumentElement());
}
protected void doRegisterBeanDefinitions(Element root) {
...
preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
...
//下面就不深入了,想了解xml的可以走这条河流
}
后续再补充这部分源码