后置处理器BeanPostProcessor

文章目录

  • spring-bean生命周期
  • BeanPostProcessor
  • InstantiationAwareBeanPostProcessor
  • SmartInstantiationAwareBeanPostProcessor
  • MergedBeanDefinitionPostProcessor
  • DestructionAwareBeanPostProcessor
  • InitDestroyAnnotationBeanPostProcessor
  • AutowiredAnnotationBeanPostProcessor
  • CommonAnnotationBeanPostProcessor
  • RequiredAnnotationBeanPostProcessor
  • PersistenceAnnotationBeanPostProcessor
  • context:component-scan
  • aop:aspectj-autoproxy

spring-bean生命周期

  1. 注解bean之指定init-method/destroy-method
  2. 实现InitializingBean/DisposableBean接口
  3. @PostConstruct和@PreDestroy注解
  4. 统一前后置处理器BeanPostProcessor

后置处理器BeanPostProcessor_第1张图片
接下来我们再来看看spring底层的实现,首先进入程序的启动类AnnotationConfigApplicationContext方法如下:

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
     
	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
     
		this();
		//注册一个或多个要处理的带注解的类。请注意,必须调用AbstractApplicationContext.refresh()才能使上下文完全处理新类。
		register(annotatedClasses);
		refresh();
	}
}
	@Override
	public void refresh() throws BeansException, IllegalStateException {
     
		synchronized (this.startupShutdownMonitor) {
     
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
     
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// 实例化并注入所有BeanPostProcessor,必须在bean实例化之前调用。
				// 常用的BeanPostProcessor有AutowiredAnnotationBeanPostProcessor,RequiredAnnotationBeanPostProcessor
				// CommonAnnotationBeanPostProcessor
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// 实例化所有的不是延迟加载(延迟加载的只有在使用的时候才会实例化)的bean实例
				// 实例化会做很多操作,包括bean生命周期内创建相关的操作都是在这操作的,比如:
				//BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization,
				//@Bean注解的initMethod,InitializingBean的afterPropertiesSet
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
     
				if (logger.isWarnEnabled()) {
     
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}
			finally {
     
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

好了初始化的逻辑部分搞清楚了,接下来我们一起来看看销毁的流程,销毁开始于applicationContext.close();方法,点进去看如下:

protected void doClose() {
     
	if (this.active.get() && this.closed.compareAndSet(false, true)) {
     
		if (logger.isInfoEnabled()) {
     
			logger.info("Closing " + this);
		}

		LiveBeansView.unregisterApplicationContext(this);

		try {
     
			// Publish shutdown event.
			publishEvent(new ContextClosedEvent(this));
		}
		catch (Throwable ex) {
     
			logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
		}

		// Stop all Lifecycle beans, to avoid delays during individual destruction.
		if (this.lifecycleProcessor != null) {
     
			try {
     
				this.lifecycleProcessor.onClose();
			}
			catch (Throwable ex) {
     
				logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
			}
		}

		// 在上下文的BeanFactory中销毁所有缓存的单例。
		// 做的事情包括:调用DisposableBean.destroy(),
		destroyBeans();

		// Close the state of this context itself.
		closeBeanFactory();

		// Let subclasses do some final clean-up if they wish...
		onClose();

		this.active.set(false);
	}
}

@bean注解的destroyMethod其实是在初始化的时候转换成DisposableBean的实现放入到了disposableBeans中

BeanPostProcessor

  1. BeanPostProcessor接口的作用

如果我们需要在Spring容器完成Bean的实例化、配置和其他的初始化前后添加一些自己的逻辑处理,我们就可以定义一个或者多个BeanPostProcessor接口的实现,然后注册到容器中去。

public interface BeanPostProcessor {
     
    /*可以在bean实例化之前调用这个方法,类似init-method,
    *这个方法可以对bean进行操作
    */
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

    /**可以在bean实例化之后调用这个方法,类似init-method,
    *这个方法可以对bean进行操作
     */
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

注意:

  • 接口中的两个方法都要将传入的bean返回,而不能返回null,如果返回的是null那么我们通过getBean方法将得不到目标。
  • BeanFactory和ApplicationContext对待bean后置处理器稍有不同。ApplicationContext会自动检测在配置文件中实现了BeanPostProcessor接口的所有bean,并把它们注册为后置处理器,然后在容器创建bean的适当时候调用它,因此部署一个后置处理器同部署其他的bean并没有什么区别。而使用BeanFactory实现的时候,bean 后置处理器必须通过代码显式地去注册,在IoC容器继承体系中的ConfigurableBeanFactory接口中定义了注册方法
  • 不要将BeanPostProcessor标记为延迟初始化。因为如果这样做,Spring容器将不会注册它们,自定义逻辑也就无法得到应用。假如你在元素的定义中使用了’default-lazy-init’属性,请确信你的各个BeanPostProcessor标记为’lazy-init=“false”’。

InstantiationAwareBeanPostProcessor

BeanPostProcessor和InstantiationAwareBeanPostProcessor这两个接口,是比较容易搞混的,需要这里注意区分一下。InstantiationAwareBeanPostProcessor代表了Spring的另外一段生命周期:实例化。先区别一下Spring Bean的实例化和初始化两个阶段的主要作用:

  • 实例化:实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中
  • 初始化:初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性

所以现在就清楚了:InstantiationAwareBeanPostProcessor是作用于 实例化 前后,所以是先执行的。BeanPostProcessor是作用于 初始化 前后,给Bean各个属性赋值的时候执行的(比如我们的属性依赖注入,都是这个时候生效的)

// 咋一看,以为方法名都一样?哈哈  其实你区分出来两个单词的意思,就明白了
// Instantiation:[ɪnstænʃɪ'eɪʃən] 实例化,例示
// Initialization:[ɪˌnɪʃəlaɪ'zeɪʃn] 初始化,设定初始值

public interface BeanPostProcessor {
     
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
     
		return bean;
	}
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
     
		return bean;
	}
}

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
     
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
     
		return null;
	}
	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
     
		return true;
	}
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
     

		return pvs;
	}
}

SmartInstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor 继承自 InstantiationAwareBeanPostProcessor;但是SmartInstantiationAwareBeanPostProcessor多了一个三个方法

// 从名字上,它有个Smart,是比较智能一些的
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
     
	// 预测Bean的类型,返回第一个预测成功的Class类型,如果不能预测返回null
	@Nullable
	default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
     
		return null;
	}
	// 选择合适的构造器,比如目标对象有多个构造器,在这里可以进行一些定制化,选择合适的构造器
	// beanClass参数表示目标实例的类型,beanName是目标实例在Spring容器中的name
	// 返回值是个构造器数组,如果返回null,会执行下一个PostProcessor的determineCandidateConstructors方法;否则选取该PostProcessor选择的构造器
	@Nullable
	default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
			throws BeansException {
     

		return null;
	}
	// 获得提前暴露的bean引用。主要用于解决循环引用的问题
	// 只有单例对象才会调用此方法
	// 在我们准们处理讲解循环引用的时候,这个方法会起到比较关键的作用
	default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
     
		return bean;
	}
}

这个接口有什么作用的呢?这里举例两个实现:1.AutowiredAnnotationBeanPostProcessor。2.依赖注入时的泛型依赖注入,就通过这个能智能判断类型来注入。

泛型依赖注入的优点:允许我们在使用spring进行依赖注入的同时,利用泛型的优点对代码进行精简,将可重复使用的代码全部放到一个类之中,方便以后的维护和修改。比如常用的Base设计。。。(属于Spring 4.0的新特性)

Spring4.0之后,这样是不报错的:

@Configuration
public class MyConfiguration {
     
	@Bean
	public BaseRepository<Student> studentRepository() {
     
		return new BaseRepository<Student>() {
     };
	}
	
	@Bean
	public BaseRepository<Faculty> facultyRepository() {
     
		return new BaseRepository<Faculty>() {
     };
	}
}
// 注意,这里能够正确注入到正确的Bean,虽然他们都是BaseRepository类型。但是在Spring4.0之后,泛型里面的东西
// 也可以作为一种分类Qualifier,随意这里虽然都是BaseRepositor类型,但是在容器中还是被分开了的
@Autowired 
private BaseRepository<Student> studentRepo; 
@Autowired 
private BaseRepository<Faculty> facultyRepo;

MergedBeanDefinitionPostProcessor

public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
     
	//来给后续回调中缓存一些meta信息使用
	void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
}

用来将merged BeanDefinition暴露出来的回调。看看它的一些主要实现:

//InitDestroyAnnotationBeanPostProcessor
	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
     
		LifecycleMetadata metadata = findLifecycleMetadata(beanType);
		metadata.checkConfigMembers(beanDefinition);
	}

//CommonAnnotationBeanPostProcessor
	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
     
		super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
		InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}

//AutowiredAnnotationBeanPostProcessor
	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
     
		InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
		metadata.checkConfigMembers(beanDefinition);
	}

//ApplicationListenerDetector
	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
     
		this.singletonNames.put(beanName, beanDefinition.isSingleton());
	}

DestructionAwareBeanPostProcessor

销毁Bean后置处理器(继承BeanPostProcessor)

postProcessBeforeDestruction:销毁后处理回调方法,该回调只能应用到单例Bean,如InitDestroyAnnotationBeanPostProcessor完成@PreDestroy注解的销毁方法调用;

public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
     

	void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;

	boolean requiresDestruction(Object bean);

}

InitDestroyAnnotationBeanPostProcessor

处理@PostConstruct和@PreDestroy

public class InitDestroyAnnotationBeanPostProcessor
		implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {
     
	// code
}

AutowiredAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor实现,自动装配带注释的字段,setter方法和任意配置方法

要注入的这些成员是通过Java 5注释检测的:默认情况下,Spring的@Autowired和@Value注释。
还支持JSR-330的@Inject注释(如果可用),作为Spring自己的@Autowired的直接替代品。

任何给定bean类中只有一个构造函数(最大值)可以携带此注释,并将’required’参数设置为true,表示构造函数在用作Spring bean时要自动装配。如果多个非必需构造函数带有注释,则它们将被视为自动装配的候选者。将选择具有最大数量依赖关系的构造函数,这些构造函数可以通过匹配Spring容器中的bean来满足。如果不能满足任何候选者,则将使用默认构造函数(如果存在)。带注释的构造函数不必是公共的。

在调用任何配置方法之前,在构造bean之后立即注入字段。这样的配置字段不必是公共的。

配置方法可以有任意名称和任意数量的参数;每个参数都将使用Spring容器中的匹配bean进行自动装配。 Bean属性setter方法实际上只是这种通用配置方法的一个特例。配置方法不必是公开的。

注意:默认的AutowiredAnnotationBeanPostProcessor将由“context:annotation-config”和“context:component-scan”XML标记注册。如果要指定自定义AutowiredAnnotationBeanPostProcessor bean定义,请删除或关闭默认注释配置。

注意:注释注入将在XML注入之前执行;因此后一种配置将覆盖通过两种方法连接的属性的前者。

除了上面讨论的常规注入点之外,这个后处理器还处理Spring的@Lookup注释,该注释标识了在运行时由容器替换的查找方法。

AutowiredAnnotationBeanPostProcessor里面包含3个内部类AutowiredFieldElement和AutowiredMethodElement和

ShortcutDependencyDescriptor,而AutowiredFieldElement和AutowiredMethodElement分别处理字段和方法的注解。

注入inject()方法被调用是在AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues方法上

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
		implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
     


	public AutowiredAnnotationBeanPostProcessor() {
       
		//后置处理器将处理@Autowire注解  
		this.autowiredAnnotationTypes.add(Autowired.class);  
		//后置处理器将处理@Value注解  
		this.autowiredAnnotationTypes.add(Value.class);  
		//获取当前类的类加载器  
		ClassLoader cl = AutowiredAnnotationBeanPostProcessor.class.getClassLoader();  
		try {
       
		    //后置处理器将处理javax.inject.Inject JSR-330注解  
		    this.autowiredAnnotationTypes.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Inject"));  
		    logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");  
		}  
		catch (ClassNotFoundException ex) {
       
		    // JSR-330 API not available - simply skip.  
		}  
	// code
}

CommonAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor这个BeanPostProcessor通过继承InitDestroyAnnotationBeanPostProcessor对@javax.annotation.PostConstruct和@javax.annotation.PreDestroy注解的支持。以及依据bean name依赖注入的@javax.annotation.Resource支持。也支持WebServiceRef注解,具有创建JAX-WS服务端点的能力。最后,处理器还支持EJB3(@EJB)。

public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
		implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
     
	// code
}
  1. 对@PostConstruct和@PreDestroy注解的处理

CommonAnnotationBeanPostProcessor继承了InitDestroyAnnotationBeanPostProcessor,这两个注解是由这个父类完成解析的,在CommonAnnotationBeanPostProcessor构造函数中调用父类的方法setInitAnnotationType()和setDestroyAnnotationType()将这两个注解Class对象传递给父类

  1. 对@Resource注解的处理

与@PostConstruct类似,先在postProcessMergedBeanDefinition中取得被@Resource标记的字段或方法,后再postProcessProperties()方法中完成对象的注入。

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
     
   super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
   //找出beanType所有被@Resource标记的字段和方法封装到InjectionMetadata中
   InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
   //将InjectionMetadata中每个被@Resource标记的字段和方法打标,防止重复计算
   metadata.checkConfigMembers(beanDefinition);
}

RequiredAnnotationBeanPostProcessor

@Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。

RequiredAnnotationBeanPostProcessor就是用来解析@Required的,当一个bean实例经过SmartInstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法时,检测bean中属性对应的setter方法被标记@Required但是用于赋值的PropertyValues对象不包含此属性就会抛出异常。如果不想对某个bean进行检测,可以将此bean的bean definition的org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.skipRequiredCheck属性设置为false。此属性默认在ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod()方法中设置为true的。

public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
		implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
     
	// code
}

PersistenceAnnotationBeanPostProcessor

PersistenceAnnotationBeanPostProcessor是Spring提供的用于处理注解@PersistenceUnit和@PersistenceContext的BeanPostProcessor。用于注解相应的JPA资源:EntityManagerFactory和EntityManager (或者它们的子类变量)。

注意 : 在目前的实现中,PersistenceAnnotationBeanPostProcessor仅仅支持@PersistenceUnit和@PersistenceContext上带有属性unitName或者不带任何属性(比如使用缺省persistence unit的情况)。如果这些注解使用在类上,并且使用了属性name,这些注解会被忽略,因为它们此时仅仅作为部署提示(参考Java EE规范)。

public class PersistenceAnnotationBeanPostProcessor
		implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor,
		MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware, Serializable {
     
	// code
}

该BeanPostProcessor从如下渠道获取EntityManagerFactory对象 :

  • Spring应用上下文定义的bean对象(缺省情况)
    这种情况下,EntityManagerFactory通常由org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean创建。

  • JNDI
    这种情况下,通常会使用jee:jndi-lookup XML配置元素,bean名称用于匹配被请求的persistence unit名称。

基于XML配置时,使用context:annotation-config或者context:component-scan 时会注册一个缺省的PersistenceAnnotationBeanPostProcessor。而基于注解的应用,比如Springboot应用,如果使用了JPA,应用也会缺省自动注册一个PersistenceAnnotationBeanPostProcessor。如果你想指定一个自定义的PersistenceAnnotationBeanPostProcessor的,需要删除或者关闭相应这样的XML配置或者注解。

context:component-scan

当遇到component-scan这样非标准或者称为自定义的元素标签时 spring会通过spring.handlers文件中的对应关系
http://www.springframework.org/schema/context= org.springframework.context.config.ContextNamespaceHandler
找到ContextNamespaceHandler 通过ContextNamespaceHandler类init()方法自动注册一些解析器 下面列出了所有以context为命名空间的组合 例如常见的context:componet-scan元素 根据注册对应关系 知道其对应的解析器为ComponentScanBeanDefinitionParser

spring-context-4.3.19.RELEASE.jar!\META-INF\spring.handlers内容

http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
http\://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler
http\://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler
public class ContextNamespaceHandler extends NamespaceHandlerSupport {
     

	@Override
	public void init() {
     
		registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
		registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
		registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
		registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
		registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
	}

}

那我们看一下的解析器ComponentScanBeanDefinitionParser的源码 (ComponentScanBeanDefinitionParser继承自BeanDefinitionParser) spring解析的时候会调用ComponentScanBeanDefinitionParser的parse()函数

//element 代表的是完整的标签
//parserContext 解析的上下文环境 能拿到一些诸如readerContext registry等变量
public BeanDefinition parse(Element element, ParserContext parserContext) {
     
    //将指定base-package拆分成string数组的形式
    String[] basePackages = StringUtils.tokenizeToStringArray(element.getAttribute(BASE_PACKAGE_ATTRIBUTE),
            ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
    // 根据xml配置或者默认配置(如果没有指定的话)配置扫描器ClassPathBeanDefinitionScanner
    ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
    //scanner扫描包下面含有特殊注解标注的类 
    //@Component @Named @ManagedBean (@Controller @Service @Repository @Configuration)都会被注册 
    Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
    // 注册组件以及一些我们常见的注解处理器(BPP) 如@Resouce @Autowired @Configuration @Value @Required @PostConstruct
    //那么以后看到属性注入(IOC/DI)的时候 就不会奇怪 这些注解的处理器(BPP)是在哪里注册的了 在这里!
    registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
    return null;
}

其中registerComponents(parserContext.getReaderContext(), beanDefinitions, element);会调用

Set<BeanDefinitionHolder> processorDefinitions =
					AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
	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());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(8);
		// @Configuration
		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));
		}
		// @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));
		}
		// @Required
		if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
     
			RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}
		
		//@PostConsruct @Resouce 等java注解
		// 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;
	}

注解以及对应的后置处理器如下表所示

注解 BPP(BeanPostProcessor)
@Configuration ConfigurationClassPostProcessor
@Autowired(@Qualifier),@Value,@Inject AutowiredAnnotationBeanPostProcessor
@Required RequiredAnnotationBeanPostProcessor
@Postconstruct,PreDestroy,@Resource CommonAnnotationBeanPostProcessor
@Persistence PersistenceAnnotationBeanPostProcessor

总的来说 component-scan 做了什么事情就比较清晰了 下面做一下总结

  1. 根据配置生成扫描类ClassPathBeanDefinitionScanner 扫描注册包下符合匹配规则的类
  2. 扫描注册被@Controller @Service @Respsitory @Component @Configuration等标注的类 因为@Controller @Service @Respsitory注解的元注解包含@Component 也就是说@Controller @Service @Respsitory本身被@Component标注 而匹配规则中有一条就是元注解包含@Component @Named 或者 @ManagedBean
  3. 注册处理如@Resouce @Autowired @PostConstruct等的BPP

aop:aspectj-autoproxy

标签注册BPP(AspectJAutoProxyBeanDefinitionParser)源码分析

对于aop这样的非标准或者称为自定义命名空间的元素 spring会从spring.handlers文件中的对应关系找到相应的处理类,然后通过init()方法注册一些处理器 aop命名空间的处理类是AopNamespaceHandler 我们看一下他的init()方法
spring-aop-4.3.19.RELEASE.jar!\META-INF\spring.handlers的文件内容

http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler

AopNamespaceHandler 的源码:

public class AopNamespaceHandler extends NamespaceHandlerSupport {
     
	@Override
	public void init() {
     
		// In 2.0 XSD as well as in 2.1 XSD.
		registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
		registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
		registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());

		// Only in 2.0 XSD: moved to context namespace as of 2.1
		registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
	}
}

从上面注册的处理器的关系我们知道 标签的处理器是AspectJAutoProxyBeanDefinitionParser 同样 这是一个继承于BeanDefinitionParser的标准的解析器 我们看一下他的parse()方法

class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
     

	@Override
	public BeanDefinition parse(Element element, ParserContext parserContext) {
     
		 //注册BPP(AnnotationAwareAspectJAutoProxyCreator)
		AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
		// 如果有子元素的话 设置属性
		extendBeanDefinition(element, parserContext);
		return null;
	}
	// code
}

parse()方法可以说主要做了一件事情就是注册了一个BPP(BeanPostProcessor) 供后续使用

你可能感兴趣的:(Spring,spring)