Spring5.1.x版本,使用注解扫描的方式
代码示例
Message
package com.huang.sourcelearn;
import org.springframework.stereotype.Component;
@Component
public class Message {
public Message() {
System.out.println(123);
}
}
Student
package com.huang.sourcelearn;
public class Student {
private String name;
public Student() {
this.name = "hsz";
}
}
Config
package com.huang.sourcelearn;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.huang.sourcelearn")
public class Config {
@Bean
public Student student() {
return new Student();
}
}
MainTest
package com.huang.sourcelearn;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
Config config = applicationContext.getBean(Config.class);
System.out.println(config);
System.out.println(applicationContext.getBean(Message.class));
System.out.println(applicationContext.getBean(Student.class));
}
}
运行结果
源码解析
从main方法中创建AnnotationConfigApplicationContext开始分析。
创建AnnotationConfigApplicationContext分析
AnnotationConfigApplicationContext构造方法
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//调用无参构造函数,会先调用父类GenericApplicationContext的构造函数
//父类的构造函数里面就是初始化DefaultListableBeanFactory,并且赋值给beanFactory
this();
// 将annotatedClasses作为bd注册到容器中
register(annotatedClasses);
refresh();
}
public AnnotationConfigApplicationContext() {
// 主要是为了解析带有注解的bean的beanDefinition,
// 注册时需要传入带有注解的类对象或类对象数组
this.reader = new AnnotatedBeanDefinitionReader(this);
// 而这个是为了扫描带有注解的类,注册为beanDefinition
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
// 使用reader来注册
this.reader.register(annotatedClasses);
}
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
}
首先会自己本身的无参构造方法,而由于java的特性,在执行无参构造方法之前又会调父类的无参构造方法,即GenericApplicationContext的无参构造方法,在这里面会为ApplicationContext中的BeanFactory实例化,创建DefaultListableBeanFactory,最终对容器的操作都是委托给这个容器实例来完成。
之后才执行自己的无参构造方法,在该方法里会实例化两个类,一个是读取注解的Bean定义读取器AnnotatedBeanDefinitionReader,一个是扫描类路径下的Bean定义的扫描器ClassPathBeanDefinitionScanner。
先看下AnnotatedBeanDefinitionReader实例化时做了啥事
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
// 跟@Condition相关的,先放着
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 看方法名就知道该方法是注册注解配置相关的processor的
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
AnnotationConfigUtils
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
/**
* 注册所有注解相关的后置处理器
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 先转成DefaultListableBeanFactory类型
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
// 主要用来解析@Order和@Priority
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
// 主要用来处理@Autowired依赖注入的,判断bean是否匹配的,是否可以注入的,
// 在后面解析依赖注入时会用到
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 注册ConfigurationClassPostProcessor,解析加了@Configuration的配置类,
// 还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解,
// 是最为重要的BeanFactory后置处理器之一
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册AutowiredAnnotationBeanPostProcessor,顾名思义就是用来处理@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));
}
// 注册CommonAnnotationBeanPostProcessor,用来处理公共注解,比如@PostConstruct和@PreDestroy还有@Resource等
// jsr250Present的值是判断是否有javax.annotation.Resource
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));
}
// 注册PersistenceAnnotationBeanPostProcessor,用来处理jpa的
// jpaPresent就是判断是否存在PersistenceAnnotationBeanPostProcessor这个类,所以需要引入spring-orm的包,没有引入的话则spring不会注册这个类
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));
}
// 注册EventListenerMethodProcessor,用来处理@EventListener注解
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));
}
// 注册DefaultEventListenerFactory
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;
}
主要是注册了一些跟注解相关的后置处理器。这几个后置处理器都是通过registerPostProcessor方法注册
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
注意,虽然说的是注册后置处理器,但其实就是注册成普通的bean定义,还不在后置处理器缓存中
在前面我们知道这个BeanDefinitionRegistry就是DefaultListableBeanFactory
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
// beanDefinition先校验下
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
// 从beanDefinitionMap获取该beanDefinition
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
// 如果已经存在同名的bean定义,则要判断是否允许覆盖,不允许覆盖则抛异常
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
// 将旧的bean定义覆盖了
this.beanDefinitionMap.put(beanName, beanDefinition);
}
// 缓存中还不存在该bean定义
else {
// 检查这个工厂的 bean 创建阶段是否已经开始,即在此期间是否有任何 bean 被标记为已创建
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// 将bean定义添加进缓存
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
// todo
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
}
接下来看下实例化ClassPathBeanDefinitionScanner
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment) {
this(registry, useDefaultFilters, environment,
(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
// 注册默认的扫描类过滤器,加了特定的注解会被扫描到:
// @Component、@Repository、@Service、@Controller、@ManagedBean、@Named
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
registerDefaultFilters调用父类ClassPathScanningCandidateComponentProvider的方法。主要就是注册了默认的扫描类过滤器,加了特定的注解会被扫描到:@Component、@Repository、@Service、@Controller、@ManagedBean、@Named。
/**
* 为@Component注册默认过滤器。
* 这将隐式注册所有具有@Component元注释的注释,包括@Repository 、 @Service和@Controller型注释。
* 还支持 Java EE 6 的javax.annotation.ManagedBean和 JSR-330 的javax.inject.Named注释(如果可用)。
*
*/
@SuppressWarnings("unchecked")
protected void registerDefaultFilters() {
// 这里只需要添加扫描@Component的过滤器,因为@Repository 、 @Service和@Controller注解都被@Component注解标注了
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
// 下面两个都需要引入相关的jar包
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.
}
}
主要就是添加一个扫描@Component的过滤器。
接下来主要就是看refresh刷新容器,refresh主要逻辑在AbstractApplicationContext类中。
留在下一篇Spring IOC 源码解析之refresh(二)分析。