Spring基础

# IoC

# XML配置

  • 同一id的Bean对象在容器中的实例,默认作用域为singleton饿汉式单例(容器创建时就完成单例对象的创建),prototype懒汉式多例(容器创建时不对对象进行创建),每次获取都会创建新的对象实例。单例模式下对象创建后调用init-method,容器销毁后调用destroy-method;原型模式下容器销毁后不会调用destroy-method

  • (使用<property>标签)对象初始化将调用无参构造器,并借助对象的setter方法为对象属性赋值;(使用<constructor-arg>标签)可改为使用含参构造器对对象进行直接初始化和赋值,若存在重载的构造器,则使用标签中的type属性指定装填参数的类型

  • 若不同Bean对象的类型相同,则不能通过getBean(类型)方法获取特定Bean

  • 通过静态工厂创建Bean对象;通过实例工厂创建Bean对象(通过工厂方法);通过FactoryBean<T>实现类创建Bean对象(懒汉式

  • <context:property-placeholder location="">标签为Bean加载外部配置文件

  • 泛型依赖注入

# 注解配置

  • 向容器注入Bean

    • @Bean
    • @Import(通过ImportSelectorBeanDefinitionRegistrar手动导入特定bean)
    • 实现FactoryBean手动注册
  • Bean生命周期方法

    • @Bean注解中手动指定initMethoddestroyMethod属性
    • 实现InitializingBean/DisposableBean指定初始化与销毁方法
    • @PostConstruct/@PreDestroy
    • 实现BeanPostProcessor拦截容器所有对象的生命周期行为
    • ApplicationContextAwareProcessor
    • InitDestroyAnnotationBeanPostProcessor
    • BeanValidationBeanPostProcessor
    • AsyncAnnotationBeanPostProcessor
  • 容器组件装配

  • @Autowired优先通过Bean类型在容器中搜索组件,若找到多个则通过Bean名称(或通过@Qualifier显式指定的Bean名称)进行进一步装配;若最终未找到相应组件,默认抛出异常(@Autowired(required=true)

    可标注在属性、Setter方法、构造器方法(或方法参数)上

    • 若组件只有一个有参构造器,则参数默认从容器中获取,无需标注@Autowired
    • 通过@Bean手动注入组件时,方法参数(如果存在)默认从容器中获取,无需标注@Autowired
  • @Resource只能按照Bean名称进行组件装配

# 生命周期

# ApplicationContext生命周期

	// AbstractApplicationContext.java

	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);
        
				// Register bean processors that intercept bean creation.
				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();

				// Instantiate all remaining (non-lazy-init) singletons.
				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();
			}
		}
	}
  1. # prepareRefresh();
    1. initPropertySource();供子类重写以构造个性化属性(如用于自定义配置中心)
    2. getEnvironment().validateRequiredProperties();检验个性化属性的合法性
    3. earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();保存容器中的部分早期事件
  2. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

    1. refreshBeanFactory();刷新(或创建❓)BeanFactory
    2. getBeanFactory();返回刚初始化的DefaultListableBeanFactory
  3. # prepareBeanFactory(beanFactory);
    1. 配置BeanFactory类加载器、表达式解析器、环境变量信息Map等组件
    2. 配置ApplicationContextAwareProcessor
    3. 忽略对EnvironmentAwareEmbeddedValueResolveAware实现类的自动配置;设置对BeanFactoryResourceLoaderApplicationEventPublisherApplicationContext组件的自动配置
    4. 配置ApplicationListenerDetector
  4. # postProcessBeanFactory(beanFactory);
    1. postProcessBeanFactory();供子类重写以在容器预初始化完成时进行进一步的设置
  5. # invokeBeanFactoryPostProcessors(beanFactory);

    BeanFactory标准初始化之后执行:

    1. 根据是否实现了PriorityOrderedOrder接口分批获取容器中所有的BeanDefinitionRegistryPostProcessor分批排序后分批执行
      1. invokeBeanDefinitionRegistryPostProcessors(Collection, BeanFactory);执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()
      2. invokeBeanFactoryPostProcessors(Collection, BeanFactory);执行BeanDefinitionRegistryPostProcessor.postProcessBeanFactory()
    2. 分批获取容器中所有的BeanFactoryPostProcessor分批排序后分批执行
      1. invokeBeanFactoryPostProcessors(Collection, BeanFactory);执行BeanFactoryPostProcessor.postProcessBeanFactory()
  6. # registerBeanPostProcessors(beanFactory);

    调用PostProcessorRegistrationDelegate的同名方法完成Bean后置处理器的注册

    1. 通过类型获取容器中所有已定义但未被创建的BeanPostProcessor,并进行统计与检查(BeanPostPrcessorChecker
    2. 分批获取容器中所有的BeanPostProcessor分批排序后分批注册BeanFactory
    3. 最后注册MergedBeanDefinitionPostProcessorApplicationListenerDetector(在Bean初始化结束后将ApplicationListener的实现类作为应用监听器组件加入容器)
  7. initMessageSource();初始化用于消息绑定与消息解析的MessageSource组件

  8. initApplicationEventMulticaster();初始化事件派发器

  9. # onRefresh();
    1. onRefresh();供子类重写以向容器中注册其他组件❓
  10. registerListeners();将容器中的所有应用监听器注册在事件派发器上,并调用multicastEvent(ApplicationEvent)派发可能存在的早期事件

  11. # finishBeanFactoryInitialization(beanFactory);

    1. ...
    2. preInstantiateSingletons();完成自定义非懒加载单例Bean的初始化
  12. # finishRefresh();
    1. initLifecycleProcessor();获取容器生命周期处理器和以对容器onRefresh()onClose()等生命周期方法进行拦截
    2. getLifecycleProcessor.onRefresh();
    3. publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件
    4. ...

# Bean生命周期

# 容器的创建与Bean的获取(Spring 4.x)
  1. 执行ClassPathXmlApplicationContext(String[] configurations, boolean refresh, ApplicationContext parent)AnnotationConfigApplicationContext(String[] configurations, boolean refresh, ApplicationContext parent)构造器

  2. 执行AbstractApplicationContext.refresh()方法:解析配置文件,读取Bean的配置信息并保存在ConfigurableListableBeanFactory对象中:

    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    

    AbstractApplicationContext.finishBeanFactoryInitialization(BeanFactory beanFactory)内的最后一步:DefaultListableBeanFactory.preInstantiateSingletons()中完成用户自定义非懒加载的单实例Bean的初始化:

    // DefaultListableBeanFactory.preInstantiateSingletons()
    
    List<String> beanNames;
    synchronized(this.beanDefinitionMap) {
      // 获取所有将要创建的Bean实例名称
      beanNames = new ArrayList<String>(this.beanDefinitionMap);
      
      for (String beanName : beanNames) {
    		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 依次创建(非抽象、单实例、非懒加载的)Bean实例
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
        	if (isFactoryBean(beanName)) {
            // 利用重写的BeanFactory.getBean(String beanName)创建Bean
          	//final BeanFactory<?> factory = (FactoryBean<?>) getBean(...)
            // boolean isEagerInit;
          	// ...
          } else {
              // 调用父类doGetBean()方法创建Bean
              getBean(beanName);
            }
        	} 
        }
      }
      
      // SmartInitializingSingleton子类事件的监听处理器
      for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
          // ...
        } else {
          smartSingleton.afterSingletonInstantiated();
        }
      }
    }
    
  3. DefaultListableBeanFactory.getBean(String beanName)中调用父类doGetBean(..)

    // AbstractBeanFactory.doGetBean(String name, Class<T> requiredType, Object[] args, boolean typeCheckOnly)
    // ...
    
    Object sharedInstance = getSingleton(beanName); // 尝试从单实例Bean缓存(ConcurrentHashMap<String, Object> singletonObjects,单例池)中尝试获取已经创建完成的Bean实例
    if (sharedInstance != null && args == null) {
      // 已找到先前创建的Bean实例
      // ...
    } else {
      // 未找到先前创建的Bean实例
      // ...
      markBeanAsCreated(beanName);
      try {
        final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
        // ...
        // 获取依赖Bean
      	String[] dependsOn = mbd.getDependsOn();
        if (dependsOn != null) {
        	// 存在依赖Bean,则递归调用getBean(String beanName)对其进行创建
          // ...
        }
        
        if (mbd.isSingleton()) {
          // ...
          sharedInstance = getSingleton(beanName, new ObjectFactory<Object> {
            @Override
            public Object getObject() {
              try {
                return createBean(beanName, mbd, args); // 真正实现Bean实例的初始化
              }
            }
          }
        }
     }
    }
    
    # Spring如何解决循环依赖?

    答:Spring通过三级缓存解决了循环依赖,其中一级缓存为单例池singletonObjects,二级缓存为早期曝光对象earlySingletonObjects,三级缓存为单例对象工厂singletonFactories

    当A、B两个类发生循环引用时,在A完成实例化后,使用实例化后的对象创建对象工厂,并添加到三级缓存中:如果A被AOP代理,那么工厂中的是A代理后的对象,如果A没有被AOP代理,那么工厂中的是A原本实例化的对象。

    当A在初始化过程中进行属性注入时,会进行B的创建,由于B依赖了A,故创建B的同时又会去调用getBean(a)来获取A,此时会从三级缓存中进行获取(尚未初始化完成的A):

    1. 先获取三级缓存中的对象工厂
    2. 调用对象工厂的getObject()方法获取A,将其注入到B中。此后B完成后续的初始化流程

    A等待B初始化完成后将B再注入到属性中,此时A完成后续的初始化流程

    至此,循环依赖结束

    # 为什么要使用三级缓存呢?二级缓存能解决循环依赖吗?

    答:如果使用二级缓存解决循环依赖,所有Bean在实例化后(而非初始化阶段)就必须完成AOP代理,这样违背了Spring设计的原则:即,Spring应通过AnnotationAwareAspectJAutoProxyCreator后置处理器在Bean生命周期的最后一步实现AOP代理,而非在实例化后就立即进行AOP代理

    // DefaultSingletonBeanRegistry.getSingleton(String beanName, ObjectFactory<?> singletonFactory) 将初始化完成的Bean单例加入容器
    
    synchronized(this.singletonObjects) {
        // 用ConcurrentHashMap对单实例的Bean对象进行缓存(beanName -> beanInstance)
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
       // ...
            try {
                // Bean实例的获取
                singletonObject = singletonFactory.getObject();
                // ...
            } finally {
              afterSingletonCreation(beanName, singletonObject);
            }
            // ...
            // 将Bean对象加入单实例Bean缓存(singletonObjects,单例池)中
            addSingleton(beanName, singletonObject);
        }
    }
    
# Bean实例化
  1. createBean(...)

  2. resolveBeforeInstantiation(...)

  3. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()

  4. [实例化]AbstractAutowireCapableBeanFactory.doCreateBean(...)

    AbstractAutowireCapableBeanFactory.instantiateBean(beanName, mbd),推断构造方法,创建Bean对象

  5. AbstractAutowireCapableBeanFactory.populateBean(...)

    InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()

    InstantiationAwareBeanPostProcessor.postProcessPropertyValues()

    InstantiationAwareBeanPostProcessor.applyPropertyValues()

// AbstractAutowireCapableBeanFactory.createBean(...)

// 【实例化前】尝试通过InstantiationAwareBeanPostProcessor获取该Bean的代理对象(InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation())
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// (成功获取代理对象)执行applyBeanPostProcessorsAfterInitialization(..)完成初始化后的收尾处理
// ...

// 【实例化前】(不能获取代理对象)开始Bean实例的创建
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
// AbstractAutowireCapableBeanFactory.doCreateBean(...)
  
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
  instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
  instanceWrapper = createBeanInstance(beanName, mbd, args); // 【实例化】借助AbstractAutowireCapableBeanFactory.instantiateBean(beanName, mbd),利用工厂方法直接获取或利用反射调用Bean对象的构造器完成原始Bean对象的初始化
  synchronized(mbd.postProcessingLock) {
    if (!mbd.postProcessed) {
      try {
        applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); // 遍历所有MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition()方法
      }
    }
  }
  // ...
  
  //【实例化后】开始Bean对象的属性赋值与初始化流程
  Object exposedObject = bean;
  try {
    populateBean(beanName, mbd, instanceWrapper); // 【实例化后】遍历所有InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()及postProcessPropertyValues()方法,其中前者❓,后者❓;最后执行applyPropertyValues(),借助反射调用对象Setter方法等为Bean对象属性赋值
    exposedObject = initializeBean(beanName, exposedObject, args); // 【实例化后】进行Bean初始化
  }
  
  // ...
  // 注册Bean对象的销毁方法
  registerDisposableBeanIfNecessary(beanName, bean, mbd);
  // ...
}
# Bean初始化
  1. InstantiationAwareBeanPostProcessor.initializeBean(...)
    1. BeanPostProcessor.postProcessBeforeInitialization()
    2. AbstractAutowireCapableBeanFactory.invokeInitMethods(...)
      1. [初始化]InitializingBean.afterPropertiesSet()/init()
    3. BeanPostProcessor.postProcessAfterInitialization(),尝试借助ProxyFactory构造代理对象,并放入单例池,最终获取完整的Bean对象
// AbstractAutowireCapableBeanFactory.initializeBean(final String beanName, final Object bean, Object[] args)

if (System.getSecurityManager() != null) {
  // ...
} else {
  invokeAwareMethods(beanName, bean); // 【初始化前】执行部分Aware接口回调(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware);其他有对应后置处理器的Aware接口回调发生在下一步的postProcessoBeforeInitialization()中
  // ...
  
  Object wrappedBean = bean;
  // ⓵
  wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); // 【初始化前】遍历所有BeanPostProcessors,依次执行postProcessoBeforeInitialization()方法(一旦任一个BeanPostProcessors返回null,则终止遍历)
  
  // ...
  // ⓶
  invokeInitMethods(beanName, wrappedBean, mbd); //【初始化】回调初始化方法
  // ...
  wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); // 【初始化后】遍历所有BeanPostProcessors.postProcessAfterInitialization()方法
}
// ApplicationContextAwareProcessor.postProcessBeforeInitialization(Object, String)

// 根据所实现的Aware接口类型执行不同操作
ApplicationContextAwareProcessor.invokeAwareInterfaces(Object);
// AbstractAutowireCapableBeanFactory.invokeInitMethods(...)

// 回调多种初始化方法
// 1. 是否实现InitializingBean接口(afterPropertiesSet())
// 2. 是否存在自定义init()方法

// (执行其他初始化方法)

# AOP

  1. 若被代理对象没有实现任何接口,则无法使用原生JDK动态代理,因为代理对象与被代理对象之间的唯一关联是所实现的接口

    // 在InvocationHandler.invoke(Object, Method, Object[])中对目标方法进行修饰
    Object proxy = Proxy.newProxyInstance(ClassLoader, Class<?>[], InvocationHandler)
    
  2. 若开启AOP,则容器中保存的是组件的代理对象。若组件实现了接口,则只能通过组件的接口类型访问其代理对象(JDK动态代理);若组件未实现任何接口,则可通过组件的自身类型访问其代理对象(CGLIB动态代理)

  3. 切面类中配置通知方法

    @Before/@After/@AfterReturning/@AfterThrowing/@Around

    • 通知方法的执行顺序:前置通知->后置通知->返回/异常通知

      • 通知方法注解的切入点表达式中,public为可选(只支持public方法)*匹配全部路径或单层路径,..匹配多层路径(非全部);*匹配任意类名、任意字符或单个参数,..匹配任意数量参数
    • 在(非环绕)通知方法参数中的JoinPoint对象中获取通知方法的签名和参数列表等信息;在通知方法注解的returningthrowing属性中配置接收通知方法返回值或异常的参数(JoinPoint对象在通知方法参数中必须位于首位)

    • 通知方法可拥有任意访问修饰符和返回值,但其参数表必须唯一确定(Spring通过反射查找该方法的唯一方式)

  4. 环绕通知优先于普通通知执行(仅在当前切面类范围内:环绕前置<->普通前置->目标方法->环绕后置->普通后置);必须将proceedingJoinPoint.proceed(Object[] args)结果进行返回或将异常进行抛出,否则普通通知方法无法感知通知方法的返回值或异常

若存在多个切面类,则类名字母顺序在前或@Order注解值越小的先执行

# 源码分析

# @EnableAspectJAutoProxy

利用BeanDefinitionRegistrar向容器中注册AspectJAutoProxyRegistrar,后者向BeanDefinitionRegistry中注册AnnotationAwareAspectJAutoProxyCreator

# AnnotationAwareAspectJAutoProxyCreator

# 初始化
  1. registerBeanPostProcessors(beanFactory);创建所需的BeanPostProcessor,并注册进BeanFactory
  2. finishBeanFactoryInitialization(beanFactory);创建剩余的单例Bean(如非后置处理器类型的其他Bean),完成BeanFactory初始化
# AOP相关类的包装
# AOP相关类的初始化
  1. 判断AOP关注点所在类是否已存在于缓存(advicedBeans)中
  2. 判断AOP关注点所在类是否实现了Advice/Pointcut/Advisor/AopInfrastructureBean等基础接口,或是否标注有@Aspect注解(是否是切面类)
  3. 判断是否需要跳过(当该类为AspectJPointcutAdvisor类型时跳过)
  4. 调用AOP关注点所在类的构造方法
# AOP相关类的初始化后

wrapIfNecessary(Object bean, String beanName, String cacheKey)将AOP关注点所在类包装为代理对象

  1. AbstractAdvisorAutoProxyCreator.getAdviceAndAdvisorsForBean(..)遍历所有增强器依次判断是否匹配,获取当前Bean所有能使用的增强器并排序返回(拦截器,即通知方法)
  2. 将当前Bean保存至advicedBeans
  3. 为当前Bean创建代理对象
    1. 获取所有可用的增强器,保存至proxyFactory
    2. 使用proxyFactory创建JdkDynamicAopProxyObjenesisCglibAopProxy代理对象
# AOP的执行流程

CglibAopProxy.intercept()

  1. DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(..)尝试获取关注点方法的有序拦截器链(MethodInterceptor

    List<Object> getInterceptorsAndDynamicInterceptionAdvice(
    			Advised config, Method method, @Nullable Class<?> targetClass) {
    // 遍历所有增强器,根据实现接口的不同包装为org.aopalliance.intercept.MethodInterceptor对象
      		if (advisor instanceof PointcutAdvisor) {
    				// ...
    			}	else if (advisor instanceof IntroductionAdvisor) {
    				// ...
    			} else {
    				Interceptor[] interceptors = registry.getInterceptors(advisor);
    				interceptorList.addAll(Arrays.asList(interceptors));
    			}
      	// ...
    }
    
  2. (若无法获取拦截器链)直接执行目标方法;

    (若成功获取拦截器链)将关注点方法信息以及拦截器链包装为CglibMethodInvocation对象,并调用其proceed()方法

    在该方法中链式获取所有可用的拦截器,执行其invoke(CglibMethodInvocation)方法:

    • 如果拦截器非MethodBeforeAdviceInterceptor,则继续调用CglibMethodInvocationproceed()proceed()返回之后再执行通知方法
    • 如果拦截器为MethodBeforeAdviceInterceptor(拦截器链最后一组),则先执行增强器的通知方法,再继续调用CglibMethodInvocationproceed():此处由于已遍历至拦截器链末尾,则调用invokeJoinpoint()执行切入点方法

    通过拦截器链,保证通知方法与切入点方法之间的执行顺序

# AOP自调用解决方案

# 事务

  • REQUIRED
  • SUPPORTS
  • MANDATORY
  • REQUIRES_NEW
  • NOT_SUPPORTED
  • NEVER
  • NESTED

# 编程式事务

PlatformTransactionManager接口

# 声明式事务

# AbstractPlatformTransactionManager
# @EnableTransactionManagement

通过TransactionManagementConfigurationSelector,默认向容器中导入AutoProxyRegistrarProxyTransactionManagementConfiguration,前者向容器中注册InfrastructureAdvisorAutoProxyCreator,后者向容器中注册BeanFactoryTransactionAttributeSourceAdvisor

# BeanFactoryTransactionAttributeSourceAdvisor
  1. 借助AnnotationTransactionAttributeSource中的注解解析器解析@Transactional注解配置信息
  2. TransactionInterceptor注入注解解析器与事务管理器PlatformTransactionManager(通过@Qualifier指定或从容器中获取事务管理器)
  3. 在代理对象执行目标方法时,通过事务拦截器链(中的事务管理器)进行事务控制

# 扩展组件

# BeanFactoryPostProcessor

BeanFactoryPostProcessor.postProcessBeanFactory()

在BeanFactory标准初始化完成后调用,此时Bean定义信息已被加载至BeanFactory,但尚未进行实例化

# BeanDefinitionRegistryPostProcessor

在Bean定义信息将被加载至BeanFactory之前调用

先执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry(),再执行BeanDefinitionRegistryPostProcessor.postProcessBeanFactory(),再执行BeanFactoryPostProcessor的回调方法

用于在BeanFactory初始化完成之前向容器工厂添加额外的组件

# ApplicationListener

监听容器内发布的事件(事件继承至ApplicationEvent

@EventListener

借助EventListenerMethodProcessor解析注解上的事件监听信息,而该方法处理器实现了SmartInitializingSinglton接口

# SmartInitializingSingleton

在容器内所有非懒加载的单例Bean都初始化完成(finishBeanFactoryInitialization(beanFactory))后,容器结束刷新(finishRefresh())前调用