在使用SpringBoot做提测平台项目的过程中,经常使用AutoWired注解实现bean的自动注入,这些都是AutowiredAnnotationBeanPostProcess类实现的,最近抽空分析了下自动注入的原理,以下分析记录相关主要流程。
我们项目一般都有个启动主类,如下所示
@SpringBootApplicationpublic class TestFlowApplication {public static void main(String[] args) {SpringApplication.run(TestFlowApplication.class, args);}}
在调用run方法后,会调用SpringApplication中的run(String... args)方法,我们主要分析相关的流程
//变参run方法public ConfigurableApplicationContext run(String... args) {StopWatch stopWatch = new StopWatch();stopWatch.start();ConfigurableApplicationContext context = null;Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();configureHeadlessProperty();//get方法直接new SpringApplicationRunListeners对象,其中包含SpringApplicationRunListener列表//列表中当前封装了实现SpringApplicationRunListener接口的EventPublishingRunListenerSpringApplicationRunListeners listeners = getRunListeners(args);listeners.starting();try {ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);//准备环境,分发环境准备事件,处理事件流程中,会创建bootstrap父容器,在后面会分析这块ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);......//创建容器,实际在创建bootstrap容器过程中注册了AutowiredAnnotationBeanPostProcesscontext = createApplicationContext();......prepareContext(context, environment, listeners, applicationArguments, printedBanner);refreshContext(context);afterRefresh(context, applicationArguments);stopWatch.stop();......}catch (Throwable ex) {......}......return context;}......//准备环境,实际就是分发ApplicationEnvironmentPreparedEvent给listenerprivate ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,ApplicationArguments applicationArguments) {// Create and configure the environmentConfigurableEnvironment environment = getOrCreateEnvironment();configureEnvironment(environment, applicationArguments.getSourceArgs());//调用listeners的environmentPrepared方法,遍历上面说的listeners列表分发ApplicationEnvironmentPreparedEvent事件listeners.environmentPrepared(environment);......return environment;}
在EventPublishingRunListener执行environmentPrepared方法中,会调用
SimpleApplicationEventMulticaster广播ApplicationEnvironmentPreparedEvent事件
@Overridepublic void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));Executor executor = getTaskExecutor();//获取ApplicationListeners,其中BootstrapApplicationListener实现了 ApplicationListener<ApplicationEnvironmentPreparedEvent>接口for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {if (executor != null) {executor.execute(() -> invokeListener(listener, event));}else {//执行BootstrapApplicationListener的onApplicationEvent方法invokeListener(listener, event);}}}//BootstrapApplicationListener对应EnvironmentPreparedEvent处理方法@Overridepublic void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {......ConfigurableApplicationContext context = null;String configName = environment.resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}");for (ApplicationContextInitializer<?> initializer : event.getSpringApplication().getInitializers()) {if (initializer instanceof ParentContextApplicationContextInitializer) {context = findBootstrapContext((ParentContextApplicationContextInitializer) initializer,configName);}}//刚启动当前bootstrap容器还未创建if (context == null) {//这里会创建父级容器bootstrap容器context = bootstrapServiceContext(environment, event.getSpringApplication(),configName);......}......}
在BootstrapApplicationListener的bootstrapServiceContext方法中,会创建bootstrap容器
private ConfigurableApplicationContext bootstrapServiceContext(ConfigurableEnvironment environment, final SpringApplication application,String configName) {StandardEnvironment bootstrapEnvironment = new StandardEnvironment();MutablePropertySources bootstrapProperties = bootstrapEnvironment.getPropertySources();//构造属性的一些流程,忽略......//这里构造了一个SpringApplicationBuilder// TODO: is it possible or sensible to share a ResourceLoader?SpringApplicationBuilder builder = new SpringApplicationBuilder().profiles(environment.getActiveProfiles()).bannerMode(Mode.OFF).environment(bootstrapEnvironment)// Don't use the default properties in this builder.registerShutdownHook(false).logStartupInfo(false).web(WebApplicationType.NONE);final SpringApplication builderApplication = builder.application();if(builderApplication.getMainApplicationClass() == null){builder.main(application.getMainApplicationClass());}if (environment.getPropertySources().contains("refreshArgs")) {builderApplication.setListeners(filterListeners(builderApplication.getListeners()));}builder.sources(BootstrapImportSelectorConfiguration.class);//执行builder的run方法,这里还是会调用SpringApplication的run方法final ConfigurableApplicationContext context = builder.run();// gh-214 using spring.application.name=bootstrap to set the context id via// `ContextIdApplicationContextInitializer` prevents apps from getting the actual// spring.application.name// during the bootstrap phase.//当前容器唯一标识为bootstrapcontext.setId("bootstrap");......return context;}
由上分析的流程可知,最后又回到了SpringApplication中的run方法,其中执行createApplicationContext方法创建context
public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."+ "annotation.AnnotationConfigApplicationContext";......//创建ConfigurableApplicationContextprotected ConfigurableApplicationContext createApplicationContext() {Class<?> contextClass = this.applicationContextClass;if (contextClass == null) {try {//由于是bootstrap容器,webApplicationType为noneswitch (this.webApplicationType) {case SERVLET:contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);break;case REACTIVE:contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);break;default://当前类为class org.springframework.context.annotation.AnnotationConfigApplicationContextcontextClass = Class.forName(DEFAULT_CONTEXT_CLASS);}}catch (ClassNotFoundException ex) {throw new IllegalStateException("Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass",ex);}}//通过反射创建类实例,通过构造方法反射创建return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);}
在反射创建AnnotationConfigApplicationContext过程中,调用无参构造方法
//注解bean读取器private final AnnotatedBeanDefinitionReader reader;//根据类路径bean扫描器private final ClassPathBeanDefinitionScanner scanner;......public AnnotationConfigApplicationContext() {//这里创建了reader,在这里才是AutowiredAnnotationBeanPostProcess注册的关键this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}
在执行this.reader = new AnnotatesBeanDefinitionReader(this)时,会调用AnnotationConfigUtils.registerAnnotationConfigProcessors()方法注册多个BeanPostProcessor类,包括AutowiredAnnotationBeanPostProcessor
public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalAutowiredAnnotationProcessor";public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {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());}}Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);//这里注册了名称为AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME,value为 RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class)beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));}// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition();try {def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));}catch (ClassNotFoundException ex) {throw new IllegalStateException("Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);}def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));}if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));}return beanDefs;}
经过了上述流程的分析,我们对AutowiredAnnotationBeanPostProcess注册过程就比较清楚了




