Spring从2.5开始支持基于注解的bean扫描,考虑到目前流行的SpringBoot框架也是大量采用了注解驱动开发,所以本文直接跨过xml配置,从注解驱动开始,一探究竟为什么加了@Service,就可以直接在Spring中注入并调用方法了?
1、初始化AnnotationConfigApplicationContext
入口代码:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {this();register(componentClasses);refresh();}
1.1 构造函数,首先需要调用无参构造函数
//调用父类无参的构建函数new出一个DefaultListableFactorypublic AnnotationConfigApplicationContext() {/*** 1.2 初始化基于注解的beanDefinition扫描器* 把处理注解的bean定义 放入到容器中*/this.reader = new AnnotatedBeanDefinitionReader(this);//1.3初始化 基于classpath的beanDefinition扫描器 默认使用的是这个this.scanner = new ClassPathBeanDefinitionScanner(this);}
在调用无参构造函数的时候,由于AnnotationConfigApplicationContext继承了GenericApplicationContext类。根据类的初始化顺序,是会先初始化父类的构造函数,所以在执行AnnotationConfigApplicationContext的无参的构造函数的时候,先调用了GenericApplicationContext()。:
/*** Create a new GenericApplicationContext.* @see #registerBeanDefinition* @see #refresh*/public GenericApplicationContext() {this.beanFactory = new DefaultListableBeanFactory();}
这个就是我们经常说的Spring的容器类DefaultListableBeanFactory。
1.2、初始化基于注解的beanDefinition扫描器
初始化基于注解的beanDefinition扫描器。把处理注解的bean定义 放入到容器中
public AnnotationConfigApplicationContext() {// 初始化基于注解的beanDefinition扫描器.// 把处理注解的bean定义 放入到容器中this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {.....//传递过来的 AnnotationConfigApplicationContext bean定义 容器this.registry = registry;/*** 用于计算判断 {@link Conditional} 注解*/this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);/*** 1.1.1注册 所相关注解的后置处理器 到registry*/AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}
- 几个细节问题看一下,我们可以看到传到
AnnotatedBeanDefinitionReader()方法的第一个参数是BeanDefinitionRegistry。这个猜测就是AnnotationConfigApplicationContext的接口。一看代码果然是的。下面是关于BeanDefinitionRegistry接口的定义,从中看到这个接口主要定义的是注册,删除,获取,是否包含,判断BeanName是否使用的一些接口,也就是定义关于BeanDefinition常用操作的接口。
public interface BeanDefinitionRegistry extends AliasRegistry {void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException;void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException;BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException;boolean containsBeanDefinition(String var1);String[] getBeanDefinitionNames();int getBeanDefinitionCount();boolean isBeanNameInUse(String var1);}
- 核心逻辑是
**AnnotationConfigUtils.registerAnnotationConfigProcessors**
调用工具类注册AnnotationConfigProcessors, 也就是配置的前置处理器
而就是在这个方法中完成了对多个重要Bean的注册
/*** Register all relevant annotation post processors in the given registry.* @param registry the registry to operate on*/public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {registerAnnotationConfigProcessors(registry, null);}/*** Register all relevant annotation post processors in the given registry.* @param registry the registry to operate on* @param source the configuration source element (already extracted)* that this registration was triggered from. May be {@code null}.* @return a Set of BeanDefinitionHolders, containing all bean definitions* that have actually been registered by this call*/public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, 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());}}// 1、BeanDefinitionHolder只是存放BD的,里面有三个属性:BD对象、beanName以及别名组成的String[]Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);// 注册最关键的类,对应的类为ConfigurationClassPostProcessor,父类的父类是BeanFactoryPostProcessor// 判断register是否包含 internalConfigurationAnnotationProcessor名称的BeanDefinition,初始化是不包含的if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);// 将BD注入进容器中,没经过什么处理,只是放入了DefaultListableBeanFactory中的beanDefinitionMap跟存放beanName的list中beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}// 此类实现了BeanPostProcessor,用于处理@Autowired、@Value注解if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);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;}
- 这段代码是核心逻辑,我们首先看看第一个比较重要的类
BeanDefinitionHolder。BeanDefinitionHolder是BeanDefinition的封装类, 封装了BeanDefinition、Bean的名字和别名, 用它来完成向IoC容器注册 - 这这一段后面一直重复的逻辑
/*** The bean name of the internally managed Configuration annotation processor.*/public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalConfigurationAnnotationProcessor";Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);// 将BD注入进容器中,没经过什么处理,只是放入了DefaultListableBeanFactory中的beanDefinitionMap跟存放beanName的list中beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}.....return beanDefs
registry是AnnotationConfigApplicationContext类实例,AnnotationConfigApplicationContext是继承了GenericApplicationContext类,这个类继承了抽象类AbstractApplicationContext。这个里面实现了containsBeanDefinition(String beanName)方法。这个方法,最终还是调用的是DefaultListableBeanFactoryBean工厂的方法containsBeanDefinition(beanName)完成的。
new RootBeanDefinition(ConfigurationClassPostProcessor.class);创建的是BeanDefinition的定义registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)这行代码会调用GenericApplicationContext的registerBeanDefinition(beanName,beanDefinition)方法,然后这个方法就是会获取到DefaultListableBeanFactoryBean工厂的registerBeanDefinition方法。这个方法会放入到DefaultListableBeanFactory的this.beanDefinitionMap属性中存起来。 ```java private static BeanDefinitionHolder registerPostProcessor(
}BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {// BD设置roledefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);// 把该BD放入到beanDefinitionMap和beanDefinitionNamesregistry.registerBeanDefinition(beanName, definition);// 生成BDHoderreturn new BeanDefinitionHolder(definition, beanName);
@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { // 代码省略 if (hasBeanCreationStarted()) { ….. } else { // Still in startup registration phase // 放入到beanDefinitionMap和beanDefinitionNames this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } // 代码省略…. }
<a name="6067b6d7"></a>#### 1.3、初始化 基于classpath的beanDefinition扫描器```java//调用父类无参的构建函数new出一个DefaultListableFactorypublic AnnotationConfigApplicationContext() {/*** 1.2 初始化基于注解的beanDefinition扫描器* 把处理注解的bean定义 放入到容器中*/this.reader = new AnnotatedBeanDefinitionReader(this);//1.3初始化 基于classpath的beanDefinition扫描器 默认使用的是这个this.scanner = new ClassPathBeanDefinitionScanner(this);}
详细代码:
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {this(registry, true);}public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {this(registry, useDefaultFilters, getOrCreateEnvironment(registry));}// useDefaultFilters = truepublic ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,Environment environment, @Nullable ResourceLoader resourceLoader) {this.registry = registry;if (useDefaultFilters) {// 初始化默认的包扫描过滤器,主要是 3类注解扫描registerDefaultFilters();}// ClassPathBeanDefinitionScanner设置enviromentsetEnvironment(environment);// 设置classLoadersetResourceLoader(resourceLoader);}
核心函数是registerDefaultFilters(),看一下里面的具体的实现:
protected void registerDefaultFilters() {// 加入扫描@Component注解的过滤器,这样就能扫到 @Component注解 以及其派生注解 @Controller,@Service,Repository...// 这里的this是 ClassPathBeanDefinitionScannerthis.includeFilters.add(new AnnotationTypeFilter(Component.class));// 获取到类加载器ClassLoaderClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.}try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");}catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}}
到此完成了BeanFactory,注解后处理PostProcessor,AnnotationTypeFilter初始化(
includeFilters的加入了AnnotationTypeFilter)。
