Spring source learning -IOC (annotation scanning Register BeanDefinition)

Speaking in front of the Spring IOC basic concepts and how to resolve xml configuration is BeanDefinition. Interested can go to find the next juejin.im/post/5cea6c...

1. Basic Usage

We will join in the spring configuration file in general such a passage configured to open automatically scan.

	<context:component-scan base-package="com.study.mike.spring.service">
		<context:exclude-filter type="annotation" expression=""/>
		<context:include-filter type="annotation" expression=""/>
	</context:component-scan> 
复制代码

You can also turn on automatic scanning in the form of Java code, the first method requires a configuration class and therefore legitimate on @ Configuration, @ ComponentScan these two notes, the second way is the direct path to the package that you want to scan. Two ways to register BeanDefinition time a little different, but ultimately by calling doScan ClassPathBeanDefinitionScanner's () method scan register bean definitions.

@Configuration
@ComponentScan(basePackages="",includeFilters = { @Filter(type = FilterType.CUSTOM, classes = MyTypeFilter.class) })
public class ApplicationTest {
	public static void main(String[] args) {
		// 注解的方式1 
		ApplicationContext context1 = new AnnotationConfigApplicationContext(ApplicationTest.class);
		// 注解的方式2 
		ApplicationContext context2 = new AnnotationConfigApplicationContext("com.study.spring");
		CombatService cs2 = context2.getBean(CombatService.class);
		cs2.combating();
	}
    
}
复制代码

2. Source analysis

1. initialization time will call a default no-argument constructor to initialize AnnotatedBeanDefinitionReader and ClassPathBeanDefinitionScanner, initialization AnnotatedBeanDefinitionReader time will register some BeanFactoryPostProcessor (that implements this interface can once again handling of BeanFactory) type of BeanDefinition, these spring Bean is able to load bean by annotating key. Below is a flow diagram in accordance with the call chain Videos

The key in the code AnnotationConfigUtils

/**
 * 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, @Nullable 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());
		}
	}

	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    //注册一些BeanFactoryPostProcessor类型的bean
	if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
	//前面说的两种方式的注册BeanDefinition时机的区别就在这,java类当配置类的方式通过该实例最终调用doscan()方法
	//进行注册(该实例的的调用时机在后面章节分析)。
		RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
		def.setSource(source);
		beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
	}

	if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {//@Autowire注解 处理器
		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)) {//JSR-250 注解支持
		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)) {//JPA注解支持
		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;
}
复制代码

2. Regardless of the incoming parameter is configured java class or package path, eventually calling doscan method ClassPathBeanDefinitionScanner, and a look at the code below

read by the spring ASM bytecode manipulation library class information and the annotation information, this is the most critical class implementation class MetadataReader SimpleMetadataReader, all operations are processed in this class. Here is the call relationship

Register Beandefinition scan the entire process generally is such that if a certain part of which interested can go about debugging, with at the source.

Guess you like

Origin blog.csdn.net/weixin_34206899/article/details/91375625