Spring源码五:Bean的实例化-注解支持


Bean的实例化-注解支持

注解支持

注解的实现过程,其实就是Spring Bean的自动装配过程,存在于Srping bean的生命周期中,Spirng 中有三种bean的装配机制:
  • xml进行显示配置
  • java中进行显示配置
  • 隐式的bean发现机制和自动装配 所以要想了解Spring中的注解原理,首先需要了解注解的装配过程。

注解处理的入口

Spring初始化过程中,调用注解处理的几个主要埋点

├─ refresh
│ ├─ prepareRefresh
│ ├─ obtainFreshBeanFactory XML文件解析,component-scan属性解析
│ ├─ prepareBeanFactory
│ ├─ postProcessBeanFactory
│ ├─ invokeBeanFactoryPostProcessors
│ ├─ registerBeanPostProcessors 实例化注解处理器
│ ├─ initMessageSource
│ ├─ initApplicationEventMulticaster
│ ├─ onRefresh
│ ├─ registerListeners
│ ├─ finishBeanFactoryInitialization
│ │ ├─ getObjectForBeanInstance
│ │ ├─ getBean
│ │ │ ├─ createBean
│ │ │ │ ├─ doCreateBean
│ │ │ │ │ ├─ createBeanInstance
│ │ │ │ │ │ ├─ determineConstructorsFromBeanPostProcessors 解析构造函数是否有@Autowired
│ │ │ │ │ ├─ applyMergedBeanDefinitionPostProcessors 注解的搜集和装配过程
│ │ │ │ │ ├─ earlySingletonExposure
│ │ │ │ │ ├─ addSingletonFactory
│ │ │ │ │ ├─ populateBean
│ │ │ │ │ │ ├─ postProcessProperties 根据收集到的注解进行反射调用
│ │ │ │ │ │ │ ├─ AutowiredFieldElement.inject 解析有@Autowired注解域的注入
│ │ │ │ │ │ │ ├─ AutowiredMethodElement.inject 解析有@Autowired注解方法的注入
│ │ │ │ │ ├─ initializeBean
│ │ │ │ │ │ ├─ applyBeanPostProcessorsBeforeInitialization 解析处理@PostConstruct
│ │ │ │ │ │ ├─ invokeInitMethods
│ │ │ │ │ │ ├─ applyBeanPostProcessorsAfterInitialization AOP的入口
│ │ │ ├─ afterSingletonCreation
│ │ │ └─ addSingleton


注解的装配与收集

装配过程

1、根据xml文件 context:component-scan标签中的类路径或者@ComponentScan注解中的类路径进行扫描解析,将包含@Component和元注解为@Component的注解@Controller、@Service、@Repository还有支持 Java EE 6的@link javax.annotation.ManagedBean JSR-330的 @link javax.inject.Named的bean封装到BeanDefinition对象后,最后注册到 BeanFactory中。

2、注册注解后置处理器,主要由BeanPostProcessor来负责解析,具体包括:

  • ConfigurationClassPostProcessor: 注册@Configuration处理器。
  • AutowiredAnnotationBeanPostProcessor:注册@Autowired、@Value、@Inject(JSR-330)处理器。
  • RequiredAnnotationBeanPostProcessor:注册@Required处理器。
  • PersistenceAnnotationBeanPostProcessor:支持Jpa的条件下,处理Jpa相关注解 。
  • EventListenerMethodProcessor:注册@EventListener处理器。
  • InitDestroyAnnotationBeanPostProcessor:处理@PostConstruct、@PreDestroy 注解的解析。
  • CommonAnnotationBeanPostProcessor:在支持JSR-250条件下注册JDK中javax.annotation包中注解处理器(@PostConstruct、@PreDestroy、@Resource、@Resources、@Generated)。

注解后置处理器的收集过程

@Autowired@Resource 注解的收集过程基本一致,流程如下:

  • 1、看缓存里面有没有 InjectionMetadata对象
  • 2、从类中获取所有 Field 对象,循环 Field 对象,判断 Field 有没有@Resource注解, 如果有注解封装成 ResourceElement对象
  • 3、从类中获取所有 Method对象,循环 Method对象,判断 Method有没有@Resource 注解,如果有注解封装成 ResourceElement对象
  • 4、然后把两个 Field 和 Method封装的对象集合封装到 InjectionMetadata对象中
  • 5、最终把返回的 InjectionMetadata 对象存到ConcurrentHashMap 缓存中。


注解的装配与收集

CommonAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor支持了@PostConstruct、@PreDestroy、@Resource等注解的解析工作,但是真正对@PostConstruct、@PreDestroy两个注解的解析是由其父类InitDestroyAnnotationBeanPostProcessor来完成的

	// CommonAnnotationBeanPostProcessor的构造函数,支持了@PostConstruct、@PreDestroy
	public CommonAnnotationBeanPostProcessor() {
		setOrder(Ordered.LOWEST_PRECEDENCE - 3);
		setInitAnnotationType(PostConstruct.class);
		setDestroyAnnotationType(PreDestroy.class);
		ignoreResourceType("javax.xml.ws.WebServiceContext");
	}
	
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		//扫描@PostConstruct @PreDestroy
		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
		//扫描@Resource,扫描属性和方法上面是否有@Resource注解,如果有则收集起来封装成对象
		InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}

AutowiredAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor后置处理器,主要处理@Autowired的解析

	public AutowiredAnnotationBeanPostProcessor() {
		this.autowiredAnnotationTypes.add(Autowired.class);
		this.autowiredAnnotationTypes.add(Value.class);
		try {
			this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
					ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
			logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}
	
	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		// 扫描@Autowired,扫描属性和方法上面是否有@Autowired注解,如果有则收集起来封装成对象
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值