接下来我们再来看看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中
如果我们需要在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;
}
注意:
元素的定义中使用了’default-lazy-init’属性,请确信你的各个BeanPostProcessor标记为’lazy-init=“false”’。BeanPostProcessor和InstantiationAwareBeanPostProcessor这两个接口,是比较容易搞混的,需要这里注意区分一下。InstantiationAwareBeanPostProcessor代表了Spring的另外一段生命周期:实例化。先区别一下Spring 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 继承自 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;
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());
}
销毁Bean后置处理器(继承BeanPostProcessor)
postProcessBeforeDestruction:销毁后处理回调方法,该回调只能应用到单例Bean,如InitDestroyAnnotationBeanPostProcessor完成@PreDestroy注解的销毁方法调用;
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
boolean requiresDestruction(Object bean);
}
处理@PostConstruct和@PreDestroy
public class InitDestroyAnnotationBeanPostProcessor
implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {
// code
}
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这个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
}
CommonAnnotationBeanPostProcessor继承了InitDestroyAnnotationBeanPostProcessor,这两个注解是由这个父类完成解析的,在CommonAnnotationBeanPostProcessor构造函数中调用父类的方法setInitAnnotationType()和setDestroyAnnotationType()将这两个注解Class对象传递给父类
与@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);
}
@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是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配置或者注解。
当遇到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 做了什么事情就比较清晰了 下面做一下总结
标签
注册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) 供后续使用