spring

1. spring是什么?

1)spring是一个生态,作为构建java应用的基础设施

2)通常说的spring指的是spring framework

3)spring是一个轻量级开源容器框架,解决对象间耦合问题

4)主要提供IOC和AOP功能

2. IOC

        控制反转:将创建对象的权力由程序员转变为框架

        spring提供两个系列的容器:beanfactory、applicationcontext

        beanfactory是基础容器,提供简单实例化和获取对象

        applicationcontext继承beanfactory,并新增一些功能

        1)国际化支持 2)容器内消息机制 3)资源访问机制:扩展resourceloader、支持加载不同类型的resource

        beanfactory采用延迟加载机制,getBean时候再创建,因此适合资源比较紧张的应用,applicationcontext在容器启动创建

      

        IOC原理

        以ClassPathXmlApplicationContext为例

2.1 创建beanfactory(obtainFreshBeanFactory)

2.1.1 new DefaultListableBeanFactory

2.1.2 加载beanBeanDefinition

        如果是xml文件配置bean,则通过java dom解析,生成beanDefinition,并根据配置文件对其赋值

2.1.3 注册beanDefinition

        1)注册beanDefinition,以beanName为key,beanDefinition为值

        2)注册别名,以alias为key,beanName为值

        最终两者将会注册到容器(DefaultListableBeanFactory)的beanDefinitionMap中

2.2 准备beanFactory(prepareBeanFactory)

        设置一些基本的容器参数,包括:类加载器、EL表达式(${})解析器(填充属性)、注册基本的属性编辑器(读取设置属性)等

        添加后置处理器ApplicationContextAwareProcessor到容器BPP链中

       ps:ApplicationContextAwareProcessor在beforeInitialization中为ApplicationContextAware注入容器对象

2.3 postProcessBeanFactory

        spring并没有具体实现,留给三方框架对容器准备完成后的定制化处理

2.4 invokeBeanFactoryPostProcessors

        执行已经注册的beanFactoryPostProcessor以及其子BeanDefinitionRegistryPostProcessor,beanFactoryPostProcessor在初始化容器后的对外暴露点,允许在容器实例化bean前,读取bean定义并修改

        ps:Mybatis的MapperScannerConfigurer就是一个BeanDefinitionRegistryPostProcessor,用于扫描basepackage下的mapper接口封装成beanDefinition并注册,因此mapper接口无需手动注册

2.5 registerBeanPostProcessors

        注册BeanPostProcessors(后置处理器),将beanPostProcessors加到容器的一个list中

        注册有优先级:实现PriorityOrdered>Ordered接口>大于普通处理器

2.6 initMessageSource

        初始化messagesource国际化文件,如果用户定义则使用用户,否则使用默认发布者

2.7 initApplicationEventMulticaster

        初始化消息发布者(applicationEventMulticaster),如果用户定义则使用用户,否则使用默认发布者

2.8 registerListeners

        注册消费监听者到applicationEventMulticaster

2.9 finishBeanFactoryInitialization

        完成剩余非懒加载的bean初始化

2.9.1 查找bean对象

        遍历扫描到的beanNames集合,判断是否为factorybean(工厂bean),如果是则beanName加&,通过getBean初始化bean

        三级缓存:

        1)循环依赖:A依赖B,B依赖A

        2)singletonObjects(一级)缓存完整bean、earlySingletonObjects(二级):提前暴露bean、singletonFactories:缓存bean工厂

        3)缓存查找bean:如果一级没有则从二级获取,如果也没有,则从三级缓存中获得对象工厂(objectfactory)调用getObject,放入二级缓存同时删除三级缓存

        4)解决循环依赖:A创建过程依赖B,将A半成品(提前暴露)放到三级缓存,然后去创建B,如果B也依赖A,则可以在三级缓存中获得A的半成品并继续初始化B

        5)为何要三级缓存:涉及到AOP,如果Bean有代理,则注入的应该是代理类bean,但是没有代理类在初始化之后才创建,因此如果有循环依赖,则需要提前到objectfactory中创建

        ps:三级缓存无法解决构造器注入循环依赖问题

2.9.2 创建bean对象

        如果三级缓存中均无缓存,则需要创建

        使用不同方法创建bean

        1)工厂方法:如果配置factory-method,则调用对应的方法创建

        2)如果含多个构造器,则通过参数确定调用对应构造方法

        3)如果只有默认构造器,则通过反射调用构造器

2.6.3 属性注入

        1)从beanDefinition获得需要注入的属性

        2)通过byName(bean名)或者byType((bean类型)方式注入(反射调用set)

        @Autowired:只byType        @Resource:默认byName,也提供byType

2.6.4 初始化bean

        1)调用aware接口方法

        ps:aware(意识)、spring框架对bean是无侵入得分,bean无需感知容器,aware接口给框架内部使用,但是可以通过实现aware接口获得容器信息

        beanNameAware:获得beanName

        applicationContextAware:获得容器对象

2)执行beanPostProcessor

        在bean实例化后(before)、初始化之前(after),允许对bean加工处理(aop就是利用bbp)

3)执行初始化方法

        a. 实现initializingBean接口,调用afterPropertiesSet作为初始化方法

        b. 配置init-method方法

单例和原型模式(多例)原理类似,只是单例创建好后将被缓存,而原型模式每次将会被创建

3. AOP

        统一描述分散在对象、类、函数的横切关注点,将横切关注点与核心关注点分离

3.1 基本术语

1)joinpoint(连接点):可插入切面(横切逻辑)的点,如:方法执行前后、抛出异常前后

2)pointcut(切入点):需要进行切入的连接点

3)advice(通知):拦截后需要执行的逻辑

4)aspect(切面):aop实体概念,包含多个pointcut和advice。spring使用advisor描述,只含一个advice和pointcut

3.2 原理

        可以使用织入器的方式也可以使用注解实现AOP

        织入器:

        proxyfactory:基本织入器,不和ioc结合

        proxyfactorybean:和ioc容器结合

        aspectproxyfactory:aspect与spring结合使用,更为方便

proxyfactorybean原理

1)配置:配置advisor(包括pointcut和advice),配置proxyfactorybean(设置代理接口、代理对象、拦截链advisor)

因为是factorybean,因此在getBean时,实际会调用getObjct

proxyfactorybeangetObject逻辑为:

2)初始化拦截器链

        通过getBean初始化配置的拦截器并加到拦截器链中

3)生成代理对象

        如果对象实现了接口,则使用jdk创建代理,否则使用cglib

        jdk代理使用JdkDynamicAopProxy.getProxy,底层使用Proxy.newProxyInstance

        newProxyInstance原理:

        a. 首先查询缓存,看是否已经生成过代理

        b. 使用ProxyGenerator.generateProxyClass生成字节码,通过类加载器加载class

        c. 通过加载的class获得构造器,通过反射调用构造器完成初始化并返回

        根据接口生成的代理类,调用接口实际就是执行传入hander的invoke方法

        JdkDynamicAopProxy的invoke方法逻辑为:遍历配置的拦截器链,找出符合目标对象的拦截器,生成自己的拦截器链,然后逐步执行拦截器即可

        使用cglib,spring通过CglibAopProxy.getProxy实现

        getProxy直接创建一个enhancer,调用enhancer.create创建对象

        创建对象的原理为:

        a. 查找缓存

        b.利用ASM技术生成代理字节码,反编译可知在代理对象中重写目标类的每个方法,在重写方法中调用interceptor(传入)的intercept方法

        c.intercept和invoke类似,即遍历拦截器链,执行拦截

        d. 使用FastClass调用目标对象方法

        

        注解原理

        1. @EnableAspectJAutoProxy:开启AOP功能,实际是向容器注入后置处理器bbp

        2. bbp会拦截所有bean的初始化,如果bean需要增强,则生成代理对象返回

MVC

1. 初始化

1)tomcat启动时会去读取web.xml,创建servletcontext,这个context为整个应用共享,为spring ioc容器提供宿主环境

2)初始化IOC容器 如下方式

a. 配置ContextLoadListener以及springioc配置,在应用启动时调用contextInitialized将初始化容器并将其设置到servletcontext;同时配置DispatcherServlet,在其init方法中初始化mvc容器,并将其作为ioc容器的子容器

b. 只配置DispatcherServlet,则将spring和mvc的配置全部加载到一个容器

3)初始化mvc组件

包括:handlermap、multipartresolver、viewresolver、hanlderadapter等

2. 处理请求

请求到达tomcat,tomcat根据注册的servlet,调用service方法

service方法

1)getHandler

a. 遍历hanldermaps,找到合适的hanldermap

hanldermap一般来说有如下几种:simpleUrlhanldermap:使用配置的方式做url映射

requesthandlermap:使用注解方式

b. 通过url查找对应的handler

如果使用注解的方式,在实例化RequestMappingHandlerMapping时,会调用其afterPropertiesSet,在这个方法中会扫描加@controller或者@requestmapping注解的类,将其注册到容器。通过以url作为key,method作为vale,缓存到自身map,然后通过url查找对应的method

c. 将配置的拦截器放入执行链中,返回执行链

2)getHandlerAdapter

controller有多种实现方式,因此有多个适配器与之相适应,多种方式如:实现Controller接口,加@controller注解等

遍历handlerAdapter,调用其support方法,判断其是否支持此handler

3)执行处理逻辑

执行拦截器前置逻辑

handler.handle方法,掉用具体处理方法

后置逻辑

ps:实现HandlerInterceptor,配置拦截器

 4) 视图渲染

        controller处理完后返回modelAndView,ViewResolver根据处理结果获取对应的view,调用view的render接口,最终渲染到浏览器

        如:BeanNameViewResolver就是根据mv中viewname,以其为beanname,找到对应bean,作为view进行处理

事务

1. 隔离级别

        支持数据库的四种隔离级别+ISOLATION_DEFAULT(使用数据库默认隔离级别)

2. 传播行为(一个事务方法调用另一个事务方法)

        required:有则加入,无则创建

        supported:有则加入,无则忽略

        mandatory:外部必须有,否则报错

        requires_news:新建一个,如果外部有则报错

        not_support:非事务运行,如果外部有则报错

        ....

3. 原理

        声明式事务采用AOP环绕增强的方式实现,在目标方法之前开启事务,在目标方法之后提交或者回滚事务

开启事务:

        1)设置autoCommit=false,关闭自动提交

        2)将数据库连接connection绑定到本地变量,保证一个线程中多个操作使用同一连接进行

回滚事务:

        1)如果是独立事务则直接回滚

        2)如果事务有嵌套,则标记为回滚,待事务链执行完后统一回滚

        3)回滚实际调用的conn.rollback

提交事务:

        1)判断是否有回滚标记,如果没有则提交

        2)如果是嵌套事务,则等待外部事务提交

        

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值