AnnotationConfigApplicationContext详解
AnnotationConfigApplicationContext 是 Spring Framework 中基于 Java 注解配置的核心容器实现类,继承自 GenericApplicationContext。
它专用于处理基于注解的配置(如 @Configuration, @ComponentScan, @Bean 等),无需 XML 配置文件。
核心参数
- AnnotatedBeanDefinitionReader reader
- ClassPathBeanDefinitionScanner scanner
是两个核心组件,分别负责 显式注册配置类 和 自动扫描包路径 的任务。
AnnotatedBeanDefinitionReader
作用: 处理 显式注册的配置类(如 @Configuration 类),解析类中的 @Bean、@Import、@ComponentScan 等注解,将其转换为 Spring 容器可识别的 BeanDefinition。
适用场景: 当通过 register(Class<?>... annotatedClasses) 方法或构造函数直接传入配置类时,由 AnnotatedBeanDefinitionReader 解析这些类。
核心功能:
- 解析 @Configuration 类中的 @Bean 方法,生成对应的 Bean 定义。
- 处理 @Import 注解,导入其他配置类。
- 处理 @ComponentScan 注解,
触发包扫描(最终委托给 ClassPathBeanDefinitionScanner)。 - 处理 @PropertySource 等环境相关注解。
java
public class ServeApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(AppConfig.class); // 显示注册配置类
applicationContext.refresh();
UserService userService = applicationContext.getBean(UserService.class);
userService.test();
}
}ClassPathBeanDefinitionScanner
作用: 扫描 指定包路径下的组件(如 @Component、@Service、@Repository 等),自动将符合条件的类注册为 BeanDefinition。
适用场景: 当通过 scan(String... basePackages) 方法或构造函数直接传入包路径时,由 ClassPathBeanDefinitionScanner 执行扫描。
核心功能:
- 根据包路径递归扫描 .class 文件。
- 过滤出带有 @Component 及其派生注解的类。
- 注册符合条件的类为 Bean 定义。
- 支持自定义过滤器(includeFilter 和 excludeFilter)。
java
public class ServeApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.scan("cn.knowledge");
applicationContext.refresh();
UserService userService = applicationContext.getBean(UserService.class);
userService.test();
}
}构造方法
Class参数构造
这个构造方法的主要作用是从给定的一个或多个组件类(例如,带有@Configuration注解的类)中读取bean定义,并自动刷新上下文以完成所有必要的初始化工作。这意味着一旦调用这个构造方法,Spring容器就会被启动,并准备好管理bean的生命周期和依赖注入等操作。
java
/**
* Create a new AnnotationConfigApplicationContext, deriving bean definitions
* from the given component classes and automatically refreshing the context.
* @param componentClasses one or more component classes — for example,
* {@link Configuration @Configuration} classes
* 主要用于基于给定的组件类(如带有@Configuration注解的类)来创建Spring的应用程序上下文,
* 并且会自动刷新这个上下文以完成所有必要的初始化工作
*/
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 构造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
this();
register(componentClasses);
refresh();
}参数可以是
- 一个基于注解定义的普通Bean
当Bean是一个普通Bean时,构造器方法中会直接将其解析为一个BeanDefinition并加入到注册器(容器)内 - 带有@ComponentScan注解的扫描Bean
当Bean时一个带有@ComponentScan注解的扫描Bean时
java
public class ServeApplication {
public static void main(String[] args) {
// AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(UserService.class);
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Appconfig.class);
UserService userService = applicationContext.getBean(UserService.class);
userService.test();
}
}java
@ComponentScan("cn.knowledge")
public class AppConfig {
}java
package cn.knowledge.service;
@Component
public class UserService {
public void test(){
System.out.println("userService");
}
}