SpringCode
  1. Spring 是如何默认开启循环依赖的?如何关闭支持循环依赖?

  2. @Autowired和@Resource区别

    @Autowired由AutowiredAnnotationBeanPostProcessor后置处理器解析,@Resource由CommonAnnotationBeanPostProcessor解析

  3. 循环依赖的实现

    /** Cache of singleton objects: bean name to bean instance. */
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

    /** Cache of singleton factories: bean name to ObjectFactory. */
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

    /** Cache of early singleton objects: bean name to bean instance. */
    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

    singletonObjects 单例池 Spring容器 一级缓存 存储的是bean

    singletonFactories 工厂 二级缓存 存储的是对象(半成品的bean)

    earlySingletonObjects 三级缓存

    三级缓存put一个从二级缓存中生产出来的一个对象

    为什么需要三级缓存?因为防止重复创建,提高效率

  4. Spring的生命周期

    new

    init 生命周期的初始方法 @PostConstruct

    注入

    代理 aop

    put singletonObjects

  5. Spring的refresh()

    • prepareRefresh() refresh前的预处理

      // Prepare this context for refreshing.
      prepareRefresh();
      1. initPropertySources() 初始化一些属性设置;子类自定义个性化的属性设置方法;

      2. getEnvironment().validateRequireProperties() 检验属性的合法等;

      3. earlyApplicationEvents = new LinkedHashSet<>(); 保存容器中的一些早期事件;

    • 获取BeanFactory

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

      protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
      refreshBeanFactory();
      return getBeanFactory();
      }
      1. refreshBeanFactory(); 刷新(创建)BeanFactory;
      public GenericApplicationContext() {
      this.beanFactory = new DefaultListableBeanFactory();
      }

      @Override
      protected final void refreshBeanFactory() throws IllegalStateException {
      if (!this.refreshed.compareAndSet(false, true)) {
      throw new IllegalStateException(
      "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
      }
      // 设置id
      this.beanFactory.setSerializationId(getId());
      }
      1. getBeanFactory(); 返回刚才GenericApplicationContext创建的BeanFactory对象;

      2. 将创建的BeanFactory(DefaultListableBeanFactory)对象;

    • prepareBeanFactory(beanFactory); BeanFactory的预准备工作(BeanFactory的一些设置)

      protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
      // Tell the internal bean factory to use the context's class loader etc.
      // 1. 设置BeanFactory的类加载器、支持表达式解析器等
      beanFactory.setBeanClassLoader(getClassLoader());
      beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
      beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

      // Configure the bean factory with context callbacks.
      // 2. 添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
      beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
      // 3. 设置忽略的自动装配的接口 beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
      beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
      beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
      beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
      beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
      beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

      // BeanFactory interface not registered as resolvable type in a plain factory.
      // MessageSource registered (and found for autowiring) as a bean.
      // 4. 注册可以解析的自动装配(直接在任何组件中自动注入)
      beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
      beanFactory.registerResolvableDependency(ResourceLoader.class, this);
      beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
      beanFactory.registerResolvableDependency(ApplicationContext.class, this);

      // Register early post-processor for detecting inner beans as ApplicationListeners.
      // 5. 添加BeanPostProcessor【ApplicationListenerDetector】
      beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

      // Detect a LoadTimeWeaver and prepare for weaving, if found.
      // 6. 添加编译时的AspectJ
      if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
      }

      // Register default environment beans.
      // 7. 给BeanFactory注册一些能用的组件
      if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
      }
      if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
      }
      if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
      }
      }
    • // Allows post-processing of the bean factory in context subclasses.
      postProcessBeanFactory(beanFactory);
      

      BeanFactory准备工作完成后进行的后置处理工作;

      子类通过重写这个方法在BeanFactory创建并预准备完成以后做进一步的设置;

      =========以上是BeanFactory的创建及预准备工作=========

      + invokeBeanFactoryPostProcessors(beanFactory); 执行BeanFactoryPostProcessor

      BeanFactoryPostProcessor:BeanFactory的后置处理器,在BeanFactory标准初始化之后执行;

      两个接口:BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor;

      先执行BeanDefinitionRegistryPostProcessor:

      1) 获取所有的BeanDefinitionRegistryPostProcessor;

      2) 先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor

      postProcessor.postProcessBeanDefinitionRegistry(registry);

      3) 再执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor

      postProcessor.postProcessBeanDefinitionRegistry(registry);

      4) 最后执行没有实现任何优先级或顺序接口的BeanDefinitionRegistryPostProcessor

      postProcessor.postProcessBeanDefinitionRegistry(registry);

      再执行beanFactoryPostProcessor的方法:

      1) 获取所有的BeanFactoryPostProcessor;

      2) 先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor

      postProcessor.postProcessBeanFactory(beanFactory);

      3) 再执行实现了Ordered顺序接口的BeanFactoryPostProcessor

      postProcessor.postProcessBeanFactory(beanFactory);

      4) 最后执行没有实现任何优先级或顺序接口的BeanFactoryPostProcessor

      postProcessor.postProcessBeanFactory(beanFactory);

      + registerBeanPostProcessors(beanFactory);注册BeanPostProcessor【Bean的后置处理器,拦截bean的创建过程】

      不同接口类型的BeanPostProcessor在Bean创建前后的执行时机是不一样的:

      BeanPostProcessor

      InstantiationAwareBeanPostProcessor

      DestructionAwareBeanPostProcessor

      SmartInstantiationAwareBeanPostProcessor

      MergedBeanDefinitionPostProcessor【internalPostProcessors】

      1) 获取所有的BeanPostProcessor;(后置处理器都可以通过PriorityOrdered、Ordered接口来执行优先级)

      2) 先注册PriorityOrdered优先级接口的BeanPostProcessor

      把每一个BeanPostProcessor添加到Beanfactory中

      ```java
      /**
      * Register the given BeanPostProcessor beans.
      */
      private static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
      for (BeanPostProcessor postProcessor : postProcessors) {
      beanFactory.addBeanPostProcessor(postProcessor);
      }
      }
      3) 再注册Ordered接口的; 4) 最后注册没有实现任何优先级接口的; 5) 最终注册MergedBeanDefinitionPostProcessor; 6) 注册一个ApplicationListenerDetector; 在Bean创建完成后检查是否是ApplicationListener,如果是,则 applicationContext.addApplicationListener((ApplicationListener<?>) bean);
      // Re-register post-processor for detecting inner beans as ApplicationListeners,
      // moving it to the end of the processor chain (for picking up proxies etc).
      beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    • initMessageSource(); 初始化MessageSource组件(做国际化功能,消息绑定,消息解析)

      1. 获取BeanFactory;

      2. 看容器中是否有id为messageSource,类型为MessageSource的组件;

      若有则赋值给messageSource,若没有则new DelegatingMessageSource();

      MessageSource:取出国际化配置文件中的某个key值(能按照区域信息获取);

      1. 把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值时,可以自动注入MessageSource;

      beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);

      MessageSource.getMessage(String code, @Nullable Object[] args, Locale locale)

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

      1. 获取BeanFactory;

      2. 从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster;

      3. 如果上一步没有配置,则创建 new SimpleApplicationEventMulticaster(beanFactory);

      4. 将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入;

    • onRefresh(); 留给子容器(子类)

      子类重写这个方法,在容器刷新时可以自定义逻辑;

    • registerListeners(); 将容器中所有项目里面的ApplicationListener注册进来

      1. 从容器中拿到所有的ApplicationListener

      2) 将每个监听器添加到事件派发器中

      // Register statically specified listeners first.
      for (ApplicationListener<?> listener : getApplicationListeners()) {
      getApplicationEventMulticaster().addApplicationListener(listener);
      }
      1. 派发之前步骤产生的事件
    • finishBeanFactoryInitialization(beanFactory); 初始化所有剩下的单实例bean

      beanFactory.preInstantiateSingletons();

      1. 获取容器中的所有Bean,依次进行初始化和创建对象

      2. 获取Bean的定义信息:RootBeanDefinition

      3. Bean不是抽象的,是单实例的,不是懒加载的:

      ​ 1) 判断是否是FactoryBean:是否是实现FactoryBean接口的Bean;

      ​ 2) 不是FactoryBean,利用getBean(beanName);创建对象;

      ​ doGetBean(name, null, null, false);

      1. 先获取缓存中保存的单实例Bean,如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来);

      从private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); 中获取

      1. 缓存中获取不到,开始Bean的创建对象流程;

      2. 标记当前bean已经被创建;

      3. 获取Bean的定义信息;

      4. 获取当前Bean依赖的其他Bean,若有 则按照getBean()把依赖的Bean先创建出来;

      5. 启动单实例Bean的创建流程;

      ​ 1) createBean(beanName, mbd, args);

      ​ 2) Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 让BeanPostProcessor先拦截返回代理对象

      InstantiationAwareBeanPostProcessor 提前执行

      先触发postProcessBeforeInstantiation();

      如果有返回值,触发postProcessAfterInitialization();

      ​ 3) 如果前面的InstantiationAwareBeanPostProcessor 没有返回代理对象,则执行4);

      ​ 4) Object beanInstance = doCreateBean(beanName, mbdToUse, args); 创建Bean

      ​ 1) 创建Bean实例:createBeanInstance(beanName, mbd, args);

      ​ 利用工厂方法或者对象的构造器创建出Bean实例;

      ​ 2) applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

      ​ 调用MergedBeanDefinitionPostProcessor 的postProcessMergedBeanDefinition(mbd, beanType, beanName);

      ​ 3) 【Bean属性赋值】populateBean(beanName, mbd, instanceWrapper);

      ​ 赋值之前:

      ​ 1) 拿到InstantiationAwareBeanPostProcessor后置处理器:postProcessAfterInstantiation();

      ​ 2) 拿到InstantiationAwareBeanPostProcessor后置处理器:postProcessPropertyValues();

      ​ 赋值:

      ​ 3) 应用Bean属性的值,为属性利用setter方法等进行赋值:applyPropertyValues(beanName, mbd, bw, pvs);

      ​ 4) 【Bean初始化】exposedObject = initializeBean(beanName, exposedObject, mbd);

      ​ 1) 【执行Aware接口方法】invokeAwareMethods(beanName, bean); 执行xxxAware的方法;BeanNameAware/BeanClassLoaderAware/BeanFactoryAware

      ​ 2) 【执行后置处理器初始化之前】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

      ​ BeanPostProcessor.postProcessBeforeInitialization();

      ​ 3) 【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd);

      ​ 1) 是否是InitializingBean接口的实现,执行接口规定的初始化;

      ​ 2) 是否自定义初始化;

      ​ 4) 【执行后置处理器初始化之后】applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); BeanPostProcessor.postProcessAfterInitialization()

      ​ 5) 注册Bean的销毁方法registerDisposableBeanIfNecessary(beanName, bean, mbd);

      ​ 5) 将创建的Bean添加到缓存中SingletonObjects;

      ​ IOC容器就是这些Map,很多的Map里面保存了Bean和环境信息等;

      所有Bean都利用getBean创建完成之后,检查所有的Bean是否是SmartInitializingSingleton接口的,如果是执行afterSingletonsInstantiated();

    • finishRefresh(); 完成BeanFactory的初始化创建工作,IOC容器就创建完成

      // Clear context-level resource caches (such as ASM metadata from scanning).
      clearResourceCaches();

      // Initialize lifecycle processor for this context.
      // 初始化和生命周期有关的后置处理器LifecycleProcessor,默认从容器中找是否有LifecycleProcessor的组件,
      // 如果没有new DefaultLifecycleProcessor();加入到容器
      initLifecycleProcessor();

      // Propagate refresh to lifecycle processor first.
      // 拿到前面定义的生命周期处理器,回调onRefresh()
      getLifecycleProcessor().onRefresh();

      // Publish the final event.
      // 发布容器刷新完成事件
      publishEvent(new ContextRefreshedEvent(this));

      // Participate in LiveBeansView MBean, if active.
      LiveBeansView.registerApplicationContext(this);

    总结:

    1)Spring容器在启动时,会先保存所有注册进来的Bean的定义信息

    ​ 1)xml注册bean:

    ​ 2)注解注册bean

    2)Spring容器在合适的时机创建这些Bean

    ​ 1)用到这个Bean的时候:利用getBean创建bean,创建好以后保存在容器中;

    ​ 2)统一创建剩下所有的bean时,finishBeanFactoryInitialization()

    3)后置处理器:BeanPostProcessor

    每个bean创建完成时,都会使用各种后置处理器进行处理,来增强bean的功能;

    AutowiredAnnotationBeanPostProcessor:处理自动注入;

    AnnotationAwareAspectJAutoProxyCreator:来做AOP功能

    4)事件驱动模型

    ApplicationListener:事件监听

    ApplicationEventMulticaster:事件派发

  6. 依赖注入

    1. 构造器注入(默认无参构造)

    2. set注入

    3. @autowired

  7. Spring 常用注解

    组件类注解:

    @Component :标准一个普通的spring Bean类。

    @Repository:标注一个DAO组件类。

    @Service:标注一个业务逻辑组件类。

    @Controller:标注一个控制器组件类。

    装配bean时常用的注解:

    @Autowired:属于Spring 的org.springframework.beans.factory.annotation包下,可用于为类的属性、构造器、方法进行注值;

    @Resource:不属于spring的注解,而是来自于JSR-250位于java.annotation包下,使用该annotation为目标bean指定协作者Bean。

    @PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作;

    SpringMVC常用的注解

    @Controller :表明该类会作为与前端作交互的控制层组件,通过服务接口定义的提供访问应用程序的一种行为,解释用户的输入,将其转换成一个模型然后将试图呈献给用户。

    @RequestMapping : 这个注解用于将url映射到整个处理类或者特定的处理请求的方法。可以只用通配符;

    @RequestParam :将请求的参数绑定到方法中的参数上,有required参数,默认情况下,required=true,也就是改参数必须要传。如果改参数可以传可不传,可以配置required=false。

    @PathVariable : 该注解用于方法修饰方法参数,会将修饰的方法参数变为可供使用的uri变量(可用于动态绑定)。

    @RequestBody : @RequestBody是指方法参数应该被绑定到HTTP请求Body上。

    @ResponseBody : @ResponseBody与@RequestBody类似,它的作用是将返回类型直接输入到HTTP response body中。@ResponseBody在输出JSON格式的数据时,会经常用到。

AOP

通配符:

*匹配任意数量的字符

+匹配指定类及其子类

..一般用于匹配任意数的子包或参数

原理

  1. 织入的时机

    • 编译期(AspectJ)
    • 类加载时(AspectJ 5+)
    • 运行时(Spring AOP)
  2. 动态代理

    实现:基于接口代理,基于继承代理

    • JDK动态代理

      类:java.lang.reflect.Proxy

      接口:InvocationHandler

      只能基于接口进行动态代理

    • cglib动态代理

    • 区别

      JDK只能针对有接口的类的接口方法进行动态代理,jdk也不能对private方法进行动态代理

      cglib基于继承来实现代理,无法对static,final类进行代理,无法对private,static方法进行代理

      JDK动态代理使用Java原生的反射API进行操作,在生成类上比较高效;CGLIB使用ASM框架直接对字节码进行操作,在类的执行过程中比较高效;

    在Spring中的实现:

       public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
    Class<?> targetClass = config.getTargetClass();
    if (targetClass == null) {
    throw new AopConfigException("TargetSource cannot determine target class: " +
    "Either an interface or a target is required for proxy creation.");
    }
    if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
    return new JdkDynamicAopProxy(config);
    }
    return new ObjenesisCglibAopProxy(config);
    }
    else {
    return new JdkDynamicAopProxy(config);
    }
    }
    ...
    }

    如果目标对象实现了接口,则默认采用JDK动态代理,否则采用cglib动态代理;

    如果目标对象实现了接口,且强制cglib代理,则使用cglib动态代理;

    强制使用cglib动态代理:@EnableAspectJAutoProxy(proxyTargetClass = true)

    多个AOP如何叠加?

    责任链模式

       public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
    ...
    @Override
    @Nullable
    public Object proceed() throws Throwable {
    // We start with an index of -1 and increment early.
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
    return invokeJoinpoint();
    }

    Object interceptorOrInterceptionAdvice =
    this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
    // Evaluate dynamic method matcher here: static part will already have
    // been evaluated and found to match.
    InterceptorAndDynamicMethodMatcher dm =
    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
    Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
    if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
    return dm.interceptor.invoke(this);
    }
    else {
    // Dynamic matching failed.
    // Skip this interceptor and invoke the next in the chain.
    return proceed();
    }
    }
    else {
    // It's an interceptor, so we just invoke it: The pointcut will have
    // been evaluated statically before this object was constructed.
    return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
    }
    ...
    }

IOC

Author: Jiayi Yang
Link: https://jiayiy.github.io/2020/06/30/SpringCode/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.