Spring 注解处理流程

Spring 注解处理流程

以下内容是以springboot源码分析。

https://www.jianshu.com/p/acd1565510e3

类的注解处理流程

常用的类的注解:
@SpringBootApplication
@Controller
@Service
@Repository
@Configuration

springboot启动执行,初始上下文,扫描@SpringBootApplication注解类的以下的所有包。
SpringApplication.run()

public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        this.configureHeadlessProperty();
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting();

        Collection exceptionReporters;
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();//将类信息保存到beanDefinitionNames集合中,类注解被处理。
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);//实例化自定义bean,bean的变量注解被处理。
            this.afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }

            listeners.started(context);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

> SpringApplication.createApplicationContext() >BeanUtils.instantiateClass()> AnnotationConfigUtils.registerAnnotationConfigProcessors()>
AnnotationConfigUtils.registerPostProcessor()> GenericApplicationContext.registerBeanDefinition()> DefaultListableBeanFactory.registerBeanDefinition()方法中将beanname放入集合beanDefinitionNames中。

以上过程就是扫描并将组件注解的类信息保存到beanDefinitionNames集合中,再由AbstractApplicationContext.refresh()实例化自定义Bean。

变量的注解处理流程

常用的变量注解
@Autowired
@Resource
@Value()

我们自定义的Bean初始化是在AbstractApplicationContext的refresh()方法中调用finishBeanFactoryInitialization(beanFactory)完成的。
finishBeanFactoryInitialization(beanFactory) ==》beanFactory.preInstantiateSingletons() ==》getBean(beanName) ==》doGetBean ==》createBean ==》AbstractAutowireCapableBeanFactory.doCreateBean(…) ==》 instanceWrapper = this.createBeanInstance(…)
instanceWrapper 就是创建的bean实例,instanceWrapper 是一个包装实例,变量没有被赋值。

接下来AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(…) ==》
AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(…)方法将类的变量封装到InjectionMetadata的injectedElements里面去。
后面AbstractAutowireCapableBeanFactory.populateBean(…) > AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(…)>AutowiredAnnotationBeanPostProcessor.postProcessProperties(…)方法中

public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        InjectionMetadata metadata = this.findAutowiringMetadata(beanName, bean.getClass(), pvs);

        try {
            metadata.inject(bean, beanName, pvs);
            return pvs;
        } catch (BeanCreationException var6) {
            throw var6;
        } catch (Throwable var7) {
            throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", var7);
        }
    }

找到需要注入的哪些元数据,然后metadata.inject(注入),注入方法点进去,来到InjectionMetadata的inject方法,在一个for循环里面依次执行element.inject(target, beanName, pvs),来对属性进行注入。
AutowiredAnnotationBeanPostProcessor 的内部类 AutowiredFieldElement中的inject方法如下:

protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
            Field field = (Field)this.member;
            Object value;
            if (this.cached) {
                value = AutowiredAnnotationBeanPostProcessor.this.resolvedCachedArgument(beanName, this.cachedFieldValue);
            } else {
                DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
                desc.setContainingClass(bean.getClass());
                Set<String> autowiredBeanNames = new LinkedHashSet(1);
                Assert.state(AutowiredAnnotationBeanPostProcessor.this.beanFactory != null, "No BeanFactory available");
                TypeConverter typeConverter = AutowiredAnnotationBeanPostProcessor.this.beanFactory.getTypeConverter();

                try {
                    value = AutowiredAnnotationBeanPostProcessor.this.beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
                } catch (BeansException var12) {
                    throw new UnsatisfiedDependencyException((String)null, beanName, new InjectionPoint(field), var12);
                }

                synchronized(this) {
                    if (!this.cached) {
                        if (value == null && !this.required) {
                            this.cachedFieldValue = null;
                        } else {
                            this.cachedFieldValue = desc;
                            AutowiredAnnotationBeanPostProcessor.this.registerDependentBeans(beanName, autowiredBeanNames);
                            if (autowiredBeanNames.size() == 1) {
                                String autowiredBeanName = (String)autowiredBeanNames.iterator().next();
                                if (AutowiredAnnotationBeanPostProcessor.this.beanFactory.containsBean(autowiredBeanName) && AutowiredAnnotationBeanPostProcessor.this.beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
                                    this.cachedFieldValue = new AutowiredAnnotationBeanPostProcessor.ShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType());
                                }
                            }
                        }

                        this.cached = true;
                    }
                }
            }

            if (value != null) {
                ReflectionUtils.makeAccessible(field);
                field.set(bean, value);
            }

        }

可以看到value = AutowiredAnnotationBeanPostProcessor.this.beanFactory.resolveDependency(…)中,对需要注入的变量,进行校验,比较,匹配等工作,拿到实例。

方法的注解处理流程

@Cacheable
@PostMapping
@RequestMapping
@GetMapping

拿@Cacheable注解来说,beanFactory在创建bean时会给方法加上切点,设置了Interceptor,添加方法代理。
AbstractAutowireCapableBeanFactory.doCreateBean()>AbstractAutowireCapableBeanFactory.createBeanInstance()>
AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod()>ConstructorResolver.instantiateUsingFactoryMethod()>ConstructorResolver.instantiateUsingFactoryMethod()
>SimpleInstantiationStrategy.instantiate()>BeanUtils.instantiateClass()==>
==>ConfigurationClassEnhancer.intercept() ==> MethodProxy.invokeSuper()

public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs, MethodProxy cglibMethodProxy) throws Throwable {
            ConfigurableBeanFactory beanFactory = this.getBeanFactory(enhancedConfigInstance);
            String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
            if (BeanAnnotationHelper.isScopedProxy(beanMethod)) {
                String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
                if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
                    beanName = scopedBeanName;
                }
            }

            if (this.factoryContainsBean(beanFactory, "&" + beanName) && this.factoryContainsBean(beanFactory, beanName)) {
                Object factoryBean = beanFactory.getBean("&" + beanName);
                if (!(factoryBean instanceof ScopedProxyFactoryBean)) {
                    return this.enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
                }
            }

            if (this.isCurrentlyInvokedFactoryMethod(beanMethod)) {
                if (ConfigurationClassEnhancer.logger.isInfoEnabled() && BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
                    ConfigurationClassEnhancer.logger.info(String.format("@Bean method %s.%s is non-static and returns an object assignable to Spring's BeanFactoryPostProcessor interface. This will result in a failure to process annotations such as @Autowired, @Resource and @PostConstruct within the method's declaring @Configuration class. Add the 'static' modifier to this method to avoid these container lifecycle issues; see @Bean javadoc for complete details.", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
                }

                return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
            } else {
                return this.resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
            }
        }

版权声明:本文为weixin_40765637原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。