Spring从2.5开始支持基于注解的bean扫描,考虑到目前流行的SpringBoot框架也是大量采用了注解驱动开发,所以本文直接跨过xml配置,从注解驱动开始,一探究竟为什么加了@Service,就可以直接在Spring中注入并调用方法了?
1、初始化AnnotationConfigApplicationContext
入口代码:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
1.1 构造函数,首先需要调用无参构造函数
//调用父类无参的构建函数new出一个DefaultListableFactory
public 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)
方法。这个方法,最终还是调用的是DefaultListableBeanFactory
Bean工厂的方法containsBeanDefinition(beanName)
完成的。
new RootBeanDefinition(ConfigurationClassPostProcessor.class);
创建的是BeanDefinition
的定义registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)
这行代码会调用GenericApplicationContext
的registerBeanDefinition(beanName,beanDefinition)
方法,然后这个方法就是会获取到DefaultListableBeanFactory
Bean工厂的registerBeanDefinition
方法。这个方法会放入到DefaultListableBeanFactory
的this.beanDefinitionMap
属性中存起来。 ```java private static BeanDefinitionHolder registerPostProcessor(
}BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
// BD设置role
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 把该BD放入到beanDefinitionMap和beanDefinitionNames
registry.registerBeanDefinition(beanName, definition);
// 生成BDHoder
return 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出一个DefaultListableFactory
public 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 = true
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
this.registry = registry;
if (useDefaultFilters) {
// 初始化默认的包扫描过滤器,主要是 3类注解扫描
registerDefaultFilters();
}
// ClassPathBeanDefinitionScanner设置enviroment
setEnvironment(environment);
// 设置classLoader
setResourceLoader(resourceLoader);
}
核心函数是registerDefaultFilters()
,看一下里面的具体的实现:
protected void registerDefaultFilters() {
// 加入扫描@Component注解的过滤器,这样就能扫到 @Component注解 以及其派生注解 @Controller,@Service,Repository...
// 这里的this是 ClassPathBeanDefinitionScanner
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
// 获取到类加载器ClassLoader
ClassLoader 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
)。