@Configuration注解实现类为AnnotationConfigApplicationContext
/**
* Create a new AnnotationConfigApplicationContext that needs to be populated
* through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
*/
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
/**
* Create a new AnnotationConfigApplicationContext with the given DefaultListableBeanFactory.
* @param beanFactory the DefaultListableBeanFactory instance to use for this context
*/
public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {
super(beanFactory);
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
/**
* 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
*/
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
/**
* Create a new AnnotationConfigApplicationContext, scanning for components
* in the given packages, registering bean definitions for those components,
* and automatically refreshing the context.
* @param basePackages the packages to scan for component classes
*/
public AnnotationConfigApplicationContext(String... basePackages) {
this();
scan(basePackages);
refresh();
}
有4种构造器
- 初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner对象,它需要通过注册调用填充,然后手动刷新。
- 先使用给定的DefaultListableBeanFactory创建一个新的AnnotationConfigApplicationContext然后初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner对象
- 创建一个新的AnnotationConfigApplicationContext,从给定的组件类派生bean定义,并自动刷新上下文
- 创建一个新的AnnotationConfigApplicationContext,扫描给定包中的组件,为这些组件注册bean定义,并自动刷新上下文。
我们看里面最重要的几个方法
1.setEnvironment(将给定的自定义环境传播到底层的AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner。)
@Override
public void setEnvironment(ConfigurableEnvironment environment) {
super.setEnvironment(environment);
this.reader.setEnvironment(environment);
this.scanner.setEnvironment(environment);
}
2.setBeanNameGenerator(设置Bean名称,任何对这个方法的调用必须发生在调用register(Class…)和/或scan(String…)之前)
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
this.reader.setBeanNameGenerator(beanNameGenerator);
this.scanner.setBeanNameGenerator(beanNameGenerator);
getBeanFactory().registerSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
}
3.setScopeMetadataResolver(设置Bean的作用域,即判断注册的Bean 是原生类型(prototype)还是单例(singleton)类型,任何对这个方法的调用必须发生在调用register(Class…)和/或scan(String…)之前。)
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
this.reader.setScopeMetadataResolver(scopeMetadataResolver);
this.scanner.setScopeMetadataResolver(scopeMetadataResolver);
}
4.register(注册一个或多个要处理的组件类。 注意,为了让上下文完全处理新类,必须调用refresh())
@Override
public void register(Class<?>... componentClasses) {
Assert.notEmpty(componentClasses, "At least one component class must be specified");
this.reader.register(componentClasses);
}
5.scan(在指定的基包中执行扫描。 请注意,为了让上下文完全处理新类,必须调用refresh()。)
@Override
public void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
this.scanner.scan(basePackages);
}
6.registerBean从给定的bean类注册一个bean,使用给定的元数据信息获取一个新实例(通常声明为lambda表达式或方法引用),也可以定制它的bean定义元数据(通常声明为lambda表达式)。 这个方法可以被重写,以适应所有registerBean方法的注册机制(因为它们都委托给这个方法)。
参数: beanName—bean的名称(可能为空) bean class—bean的类 Supplier——用于创建bean实例的回调函数(在null的情况下,解析一个公共构造函数来自动连接) customizer——一个或多个用于定制工厂的BeanDefinition的回调函数,例如设置一个lazy-init或主标志
@Override
public <T> void registerBean(@Nullable String beanName, Class<T> beanClass,
@Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {
this.reader.registerBean(beanClass, beanName, supplier, customizers);
}
总结
1.通过构造器初始化初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner对象
2.在调用register()之前去,调用setScopeMetadataResolver()设置Bean的作用域并调用setBeanNameGenerator()设置Bean的名称
3.然后调用refresh()方法刷新配置文件(可以是xml配置也可以是其他)
4.最后调用registerBean()注册到容器中