上海做oocl船的公司网站,做外贸建网站,门户网站设计思路,网站域名被抢注做商标我们知道如果想使用spring注解你需要在applicationContext.xml配置文件中设置context:component-scan base-packagexxx’这样spring会帮助我们扫描你所设置的目录里面所有的Bean#xff0c;如果Bean上面有相应的Service,Controller注解#xff08;当然还有其他的#xff0c;…我们知道如果想使用spring注解你需要在applicationContext.xml配置文件中设置context:component-scan base-packagexxx’这样spring会帮助我们扫描你所设置的目录里面所有的Bean如果Bean上面有相应的Service,Controller注解当然还有其他的这里就不一一列出来那么Spring的IOC容器将会帮我实例对象设置属性。
分析spring如果实现注解驱动
还是从spring配置文件的命名空间入手不清楚的可以参考我之前的文章。找到spring-context包进入文件里面找到src/main/resources/META-INF/spring.handlers这样你可以看到一下内容
http\://www.springframework.org/schema/contextorg.springframework.context.config.ContextNamespaceHandler
http\://www.springframework.org/schema/jeeorg.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/langorg.springframework.scripting.config.LangNamespaceHandler
http\://www.springframework.org/schema/taskorg.springframework.scheduling.config.TaskNamespaceHandler
http\://www.springframework.org/schema/cacheorg.springframework.cache.config.CacheNamespaceHandler
可以看到context命名空间解析的类org.springframework.context.config.ContextNamespaceHandler所以可以直接定位到spring扫描的过程。
spring源码分析-ContextNamespaceHandler
//组件扫描
registerBeanDefinitionParser(component-scan, new ComponentScanBeanDefinitionParser());整个扫描包路径的过程如下
取出自定义base-package路径
创建ClassPathBeanDefinitionScanner对象并且设置springIOC容器所关心的注解Component换言之只要类定义上面有Component注解那么我们的扫描器就需要处理这个类。
设置BeanName生成工具(这里是生成类名的工具有默认的beanName也有自定义Service(“abc”)) 开始扫描包使用ClassReader扫描所有类可以得到类的信息对比是否有Component注解如果有生成BeanDefinitionScannedGenericBeanDefinition
注册Spring内置的BeanPostProcessor对象。默认有8个org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)主要需要注意的有四个
ConfigurationClassPostProcessor处理配置类 AutowiredAnnotationBeanPostProcessor处理Autowired帮助类注入属性 RequiredAnnotationBeanPostProcessor处理required CommonAnnotationBeanPostProcessor处理Resource帮助类注入属性
入口代码 if (annotationConfig) {//这里会注册很多内容BeanPostProcessor类SetBeanDefinitionHolder processorDefinitions AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);for (BeanDefinitionHolder processorDefinition : processorDefinitions) {compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));}}上面只是注册了所有内置Annotation工具类还没有实例化。接下来我们要进入refresh()方法看看基于注解的类实例化过程
注解类实例过程
在前面基于注解的类已经被扫描成为ScannedGenericBeanDefinition现在就要实例化了。再refresh()方法中首先需要注册前面说的内置处理Annotation类的工具类没错就是这几个
2 org.springframework.context.annotation.internalConfigurationAnnotationProcessor
3 org.springframework.context.annotation.internalAutowiredAnnotationProcessor
4 org.springframework.context.annotation.internalRequiredAnnotationProcessor
5 org.springframework.context.annotation.internalCommonAnnotationProcessor
6 org.springframework.context.event.internalEventListenerProcessor
7 org.springframework.context.event.internalEventListenerFactory
//最终这些类变为
0 {ApplicationContextAwareProcessor1792}
1 {ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor1961}
2 {PostProcessorRegistrationDelegate$BeanPostProcessorChecker2193}
3 {CommonAnnotationBeanPostProcessor2135}
4 {AutowiredAnnotationBeanPostProcessor1991}
5 {RequiredAnnotationBeanPostProcessor2107}
6 {ApplicationListenerDetector2194} 入口在registerBeanPostProcessors(beanFactory);这里会将上面的类注册到IOC容器中然后根据Bean的生命周期中的第6步设置属性依据Annotation的方式注入属性CommonAnnotationBeanPostProcessor来处理属性的注入。我们使用了Resource来配置属性。