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();
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
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);
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)