spring知识点总结篇

一概述

   spring是一个开源框架,以ioc和aop为核心,java语言的一个生态,时服务端开发的基石,springboot,springcloud等框架是以spring为基础开发的。

   IOC(Inversion of Controller,控制反转),将原本在程序中手动创建对象的控制权,交由spring框架来管理,ioc容器实际上是一个map中存放各种对象。

   IOC和DI的区别:ioc是一种实现思想,DI是具体的实现方式

        控制反转是从容器方面:容器控制应用程序的创建,并且为其提供需要调用的外部资源。

        依赖注入是从应用程序方面:应用程序依赖容器进行创建,并且注入所需要的外部资源

二源码解读

前提工作,准备serviceA,serviceB,通过autowired各自依赖,和一个切面类,一个配置类

@EnableAspectJAutoProxy
@ComponentScan("funnysoul.vip.service.spring.testcycle")
public class AppConfig {
}

  //程序入口

new AnnotationConfigApplicationContext(AppConfig.class);

AnnotationConfigApplicationContext类图

beanFactory接口:spring中的顶层接口,容器基本客户端视图。

初始化父类构造: 最主要的是GenericApplicationContxt

public GenericApplicationContext() {
   this.beanFactory = new DefaultListableBeanFactory();
}

初始化本类构造:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
   this();
   register(annotatedClasses);  向beanDefinitionMap中添加
   refresh();
}

this()

public AnnotationConfigApplicationContext() {

   /**
   主要向beanFactory接口的默认实现DefaultListableBeanFactory的beanDefinitionMap注册后置处理器
      beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); 
      beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());

      ConfigurationClassPostProcessor
      AutowiredAnnotationBeanPostProcessor
      CommonAnnotationBeanPostProcessor
      EventListenerMethodProcessor
      DefaultEventListenerFactory
   **/
   this.reader = new AnnotatedBeanDefinitionReader(this);    annotatedBeanDefinitionReade
   this.scanner = new ClassPathBeanDefinitionScanner(this);  ClassPathBeanDefinitionScanner
}

refresh方法(重点) 是继承AbstractApplicationContext的方法

1,prepareRefresh();  刷新前的准备工作

2,ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  //拿到默认DefaultListableBeanFactory

3,prepareBeanFactory(beanFactory);   //设置DefaultListableBeanFactory的属性

4,postProcessBeanFactory(beanFactory);  //空实现,可以去扩展,去设置beanFactory一些功能

5,invokeBeanFactoryPostProcessors(beanFactory);

     核心方法

// 通过getBean向spring容器中添加 ConfigurationClassPostProcessor
String[] postProcessorNames =
      beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
   if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
      processedBeans.add(ppName);
   }
}

...

  //主要去扫描bean 并添加到map中

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);  //ConfigurationClassPostProcessor
       //里面的主要方法     最终是执行ConfigurationClassPostProcessor的接口方法
       for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
          postProcessor.postProcessBeanDefinitionRegistry(registry);
       }

//实例化实现了beanFactoryPostProcessor的bean并调用接口方法
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
   nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
ConfigurationClassPostProcessor的processConfigBeanDefinitions方法
   通过这个类ConfigurationClassParser循环所有的bd,看是否加了Configuration Component ComponentScan Import ImportResource注解
   通过ComponentScanAnnotationParser去得到扫描的类classPathBeanDefinitionScaner的doScan去扫描
   本质是通过PathMatchingResourcePatternResolver的getResources方法去拿到类的信息

6,registerBeanPostProcessors(beanFactory);
   把实现了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;
}

7,

initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();

8,finishBeanFactoryInitialization(beanFactory);  bean的生命周期

    调用的是DefaultListableBeanFactory的preInstantiateSingletons方法

    该方法主要遍历map调用父类getBean(beanName)方法 

    doGetBean

    里面有个getSingleton(BeanName);

//一级缓存
Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
//二级缓存:用于中间存储,如果发生循环依赖,存储的是代理对象,否则原对象
Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
//三级缓存 对象的创建后,依赖注入之前,将工厂对象放入三级缓存中,主要解决代理对象的循环依赖问题
Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

主要逻辑为:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
   Object singletonObject = this.singletonObjects.get(beanName);
      //一级缓存没有,并且是正在创建的
   if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
      synchronized (this.singletonObjects) {
         singletonObject = this.earlySingletonObjects.get(beanName);
         二级缓存没有,是否可以从三级缓存中获取
         if (singletonObject == null && allowEarlyReference) {
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
               singletonObject = singletonFactory.getObject();
               this.earlySingletonObjects.put(beanName, singletonObject);
               this.singletonFactories.remove(beanName);
            }
         }
      }
   }
   return singletonObject;
}

createBean(beanName,mbd,args); //-->AbstractAutowireCapableBeanFactory的doCreateBean(beanName, mbdToUse, args);

doCreateBean

   实例化bean 转换成BeanWrapper。    instanceWrapper = createBeanInstance(beanName, mbd, args);

   属性填充   populateBean    中间如果注入bean不存在 会用三级缓存解决循环依赖问题

   初始化bean

       invokeAwareMethods(beanName, bean);  实现了aware接口的自调

if (bean instanceof Aware) {
   if (bean instanceof BeanNameAware) {
      ((BeanNameAware) bean).setBeanName(beanName);
   }
   if (bean instanceof BeanClassLoaderAware) {
      ClassLoader bcl = getBeanClassLoader();
      if (bcl != null) {
         ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
      }
   }
   if (bean instanceof BeanFactoryAware) {
      ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
   }
}
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);   beanPostProcessor之前已经实例化了,此时调用before方法 


    // 获取所有实现了 BeanPostProcessors 接口的类,进行遍历
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        // 核心方法:postProcessBeforeInitialization()
        Object current = beanProcessor.postProcessBeforeInitialization(result, beanName);
   

invokeInitMethods(beanName, wrappedBean, mbd);
   bean的初始化 @Bean(initMethod=" ") 或者实现InitializingBean接口的AtterPropertiesSet()方法
   先调用AtterPropertiesSet再调用Init-method指定的方法

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 调用实现了BeanPostProcessor接口的after方法
   此时bean已经初始化完成,属性已经填充,可以认为是一个完整的bean。此时是产生代理对象的时机

aop的实现

AnnotationAwareAspectJAutoProxyCreator  待补充

底层:jdk动态代理(基于接口)  cglib动态代理

*   总结:
*     1)、  @EnableAspectJAutoProxy 开启AOP功能
*     2)、 @EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
*     3)、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
*     4)、容器的创建流程:
*        1)、registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
*        2)、finishBeanFactoryInitialization()初始化剩下的单实例bean
*           1)、创建业务逻辑组件和切面组件
*           2)、AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
*           3)、组件创建完之后,判断组件是否需要增强
*              是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);
*     5)、执行目标方法:
*        1)、代理对象执行目标方法
*        2)、CglibAopProxy.intercept();
*           1)、得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
*           2)、利用拦截器的链式机制,依次进入每一个拦截器进行执行;
*           3)、效果:
*              正常执行:前置通知-》目标方法-》后置通知-》返回通知
*              出现异常:前置通知-》目标方法-》后置通知-》异常通知
 

三级缓存

在这里插入图片描述

声明式子事务底层原理

/**
* 原理:
* 1)、@EnableTransactionManagement
*        利用TransactionManagementConfigurationSelector给容器中会导入组件
*        导入两个组件
*        AutoProxyRegistrar
*        ProxyTransactionManagementConfiguration
* 2)、AutoProxyRegistrar:
*        给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 组件;
*        InfrastructureAdvisorAutoProxyCreator:?
*        利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用;

* 3)、ProxyTransactionManagementConfiguration 做了什么?
*        1、给容器中注册事务增强器;
*           1)、事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource解析事务注解
*           2)、事务拦截器:
*              TransactionInterceptor;保存了事务属性信息,事务管理器;
*              他是一个 MethodInterceptor;
*              在目标方法执行的时候;
*                 执行拦截器链;
*                 事务拦截器:
*                    1)、先获取事务相关的属性
*                    2)、再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger
*                       最终会从容器中按照类型获取一个PlatformTransactionManager;
*                    3)、执行目标方法
*                       如果异常,获取到事务管理器,利用事务管理回滚操作;
*                       如果正常,利用事务管理器,提交事务
*/

 

    

    

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值