Spring和SpringMVC
这篇文章要包括的部分
Spring 框架组成部分
定义
Spring是一个为Java应用程序提供基础性服务的轻量级IoC和AOP容器框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。常见的配置方式有两种:基于XML的配置、基于注解的配置。现在非常热门的SpringBoot就是在Spring框架的基础上做了再封装,简化了很多配置文件,更加方便了用户的使用。
关键字:
容器框架:AOP+IOC
配置方式:XML+注解
组成
Spring Core:核心类库,提供IOC服务;
Spring Context:提供框架式的Bean访问方式,以及企业级功能(JNDI、定时任务等);
Spring AOP:AOP服务;
Spring DAO:对JDBC的抽象,简化了数据访问异常的处理;
Spring ORM:对现有的ORM框架的支持;
Spring Web:提供了基本的面向Web的综合特性,例如多方文件上传;
Spring MVC:提供面向Web应用的Model-View-Controller实现。
Spring Test : 提供了对 JUnit 和 TestNG 测试的支持。
Spring JMS :Java消息服务。
IOC
站在设计者的角度
主体应该包括以下几个部分
加载Bean的配置(比如xml配置)
根据Bean的定义加载生成Bean的实例,并放置在Bean容器中
除了基础Bean外,还有常规针对企业级业务的特别Bean
对容器中的Bean提供统一的管理和调用
一些顶级接口
BeanFactory: 工厂模式定义了IOC容器的基本功能规范
BeanRegistry: 向IOC容器手工注册 BeanDefinition 对象的方法
BeanDefinition 定义了各种Bean对象及其相互的关系
ApplicationContext:IOC接口设计和实现
IOC容器初始化
将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的
Bean实例化
getbean 方法的实现思路
解析bean的真正name,如果bean是工厂类,name前缀会加&,需要去掉
无参单例先从缓存中尝试获取
如果bean实例还在创建中,则直接抛出异常
如果bean definition 存在于父的bean工厂中,委派给父Bean工厂获取
标记这个beanName的实例正在创建
确保它的依赖也被初始化
真正创建
单例时
原型时
根据bean的scope创建
解决循环依赖
三级缓存
第一层缓存(singletonObjects):单例对象缓存池,已经实例化并且属性赋值,这里的对象是成熟对象;
第二层缓存(earlySingletonObjects):单例对象缓存池,已经实例化但尚未属性赋值,这里的对象是半成品对象;
第三层缓存(singletonFactories): 单例工厂的缓存
为什么三级缓存?
首先要缓存是为了暴露半成品从而防止类似于死锁的循环依赖,
第一级缓存:不能动
第二级缓存:为了性能,不能每次都去工厂找,
第三季缓存:为了代理,你直接把半成品放过来,我再给你调用方法代理一下。
解决其他循环依赖的方法
使用@Lazy注解,延迟加载
使用@DependsOn注解,指定加载先后关系
修改文件名称,改变循环依赖类的加载顺序
Spring中的bean的生命周期
Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:(结合上图,需要有如下顶层思维)
Bean自身的方法: 这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法
Bean级生命周期接口方法: 这个包括了BeanNameAware、BeanFactoryAware、ApplicationContextAware;当然也包括InitializingBean和DiposableBean这些接口的方法(可以被@PostConstruct和@PreDestroy注解替代)
容器级生命周期接口方法: 这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
工厂后处理器接口方法: 这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器 接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
1):Bean实例化之前有BeanFactoryPostProcessor
2):Bean实例化之后,初始化时,有相关的Aware接口供我们去拿到Context相关信息
3):环绕着初始化阶段,有BeanPostProcessor(AOP的关键)
4):在初始化阶段,有各种的init方法供我们去自定义
IOC和DI的关系
(1)IOC就是控制反转,是指创建对象的控制权的转移,以前创建对象的主动权和时机是由程序自己控制的,而现在这种权力转移到Spring容器中,由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,而且程序只能从容器中获取对象。这样可以降低对象与对象之间耦合度,也利于功能的复用。DI依赖注入,和控制反转是同一个概念的不同角度的描述,即 应用程序在运行时依赖IoC容器来动态注入对象需要的外部资源。Spring 采用依赖注入的方式实现了IOC思想。反过来,IOC其实是依赖 DI 来实现的,所以IOC和DI的关系非常紧密。
(2)最直观的表达就是,IOC让对象的创建不用程序去new了,可以由spring自动生产,使用java的反射机制,根据配置文件在运行时动态的去创建对象以及管理对象,并调用对象的方法的。
(3)Spring的IOC有三种注入方式 :构造器注入、setter方法注入、根据注解注入。
AOP
概述
(1)AOP,一般称为面向切面,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。可用于权限认证、日志、事务处理。
(2)Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
动态代理
①JDK动态代理只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy类,InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。(是spring AOP的默认实现方式)
②如果代理类没有实现 InvocationHandler 接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
Spring如何解决多线程并发
线程并发其实竞争的的是数据库的connection,
在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域,因为Spring对一些Bean中非线程安全状态采用ThreadLocal进行处理,解决线程安全问题。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。
ThreadLocal会为每一个线程保存各自需要的变量,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
比如spring就把connection放入了threadlocal, 避免的threadlocal的并发争用问题。
Spring中的事务
管理事务的方式
1、 编程式事务,在代码中硬编码。(不推荐使用)
2、声明式事务,在配置文件中配置(推荐使用)
声明式事务又分为两种:
(1)基于XML的声明式事务
(2)基于注解的声明式事务
Spring 事务中的隔离级别有哪几种?
spring的事务隔离级别和数据库的隔离级别是一样的。
TransactionDefinition 接口中定义了五个表示隔离级别的常量:
TransactionDefinition.ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别,Mysql 默认采用的 REPEATABLE_READ隔离级别 Oracle 默认采用的 READ_COMMITTED隔离级别.
TransactionDefinition.ISOLATION_READ_UNCOMMITTED:未提交读
TransactionDefinition.ISOLATION_READ_COMMITTED:提交读
TransactionDefinition.ISOLATION_REPEATABLE_READ: 可重复读
TransactionDefinition.ISOLATION_SERIALIZABLE: 可序列化
Spring 事务的传播行为
https://blog.csdn.net/soonfly/article/details/70305683
Spring中的设计模式
(1)工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例;
(2)单例模式:Bean默认为单例模式。
(3)原型模式:如果选择了bean实例为protype则在需要使用bean实例时会使用原型模式快速创建bean实例。
(4)代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术;
(5)模板模式:用来解决代码重复的问题。比如. TymeleafTemplate, RedisTemplate, ElasticTemplat,RestTemplate, JmsTemplate, JpaTemplate,等等。
(6)观察者模式:定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被制动更新,如Spring中listener的实现–ApplicationListener。
(7)委派模式:Spring 提供了 DispatcherServlet 来对请求进行分发。
(8)适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller。
SpringMVC
(1)用户发送请求至前端控制器DispatcherServlet;
(2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handler;
(3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
(4)DispatcherServlet 调用 HandlerAdapter处理器适配器;
(5)HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);
(6)Handler执行完成返回ModelAndView;
(7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
(8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
(9)ViewResolver解析后返回具体View;
(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
(11)DispatcherServlet响应用户。
MyBatis (todo)
标签:
相关文章
-
无相关信息