框架

Spring

Spring是一个容器框架,外部最外围的原理是IOC和AOP

IOC:管制反转
是指将创建对象的控制权转移给Spring容器,并由Spring容器来治理对象与对象之间依赖关系,实现了对象与对象之间的关系的松耦合

外围:bean工厂,形象工厂模式

形象工厂模式解析:

  • Bean工厂:提供了bean的创立性能,提供了对bean生命周期的治理,治理了bean与bean之间的依赖关系
  • 整合其余框架,在配置文件中配置其余框架对象须要的参数就能够应用,不须要关怀其具体如何创立(如一些对象的创立须要先实例化其余对象)
  • 本人编码时,能够更好的面向接口编程,因为接口的实现类交由spring注入,接口的调用者不须要关怀实现类的具体,后续实现类的逻辑批改时,接口调用者不须要改代码,或只须要改配置文件

AOP:面向切面编程

  • 针对一些多个中央会用到的公共的行为和逻辑,抽取并封装为一个可重用的模块,并应用动静代理技术,应用反射创立指标类的代理类,在执行指标类办法的前后,可执行织入进去的切面逻辑
  • 缩小零碎中的反复代码,进步了代码的可维护性
  • 用于事务处理、日志记录、权限认证等

留神点:
Spring是一个容器,但凡在容器里的对象才会有Spring所提供的这些服务和性能
Spring对承受容器治理的全副的bean,默认采纳单例模式治理

AOP中的名词:
切面:
切点:
告诉:

Spring蕴含哪些模块?

spring core:提供了框架的根本组成部分,包含管制反转(Inversion of Control,IOC)和依赖注入(Dependency Injection,DI)性能。
spring beans:提供了BeanFactory,是工厂模式的一个经典实现,Spring将治理对象称为Bean。
spring context:构建于 core 封装包根底上的 context 封装包,提供了一种框架式的对象拜访办法。
spring jdbc:提供了一个JDBC的形象层,打消了繁缛的JDBC编码和数据库厂商特有的错误代码解析, 用于简化JDBC。
spring aop:提供了面向切面的编程实现,让你能够自定义拦截器、切点等。
spring Web:提供了针对 Web 开发的集成个性,例如文件上传,利用 servlet listeners 进行 ioc 容器初始化和针对 Web 的 ApplicationContext。
spring test:次要为测试提供反对的,反对应用JUnit或TestNG对Spring组件进行单元测试和集成测试。

动静代理

动静代理原理

动静代理不须要批改字节码,在运行时利用反射机制动静的为一个类的对象创立一个代理对象,代理对象能够在这个类的对象执行办法的前后插入一段代码逻辑,达到加强指标类办法的目标

代理类继承了Proxy类,实现了InvocationHandler接口

为什么jdk动静代理只能代理接口的办法:

  • 因为动态创建的代理类实现了被代理类的接口,只具备接口中的办法
  • 继承类曾经继承Proxy类,不能再继承代理类
  • javaassit、cglib、asm等批改字节码技术通过继承代理类实现,能够代理所有办法,被final润饰的除外

jdk动静代理与cglib动静代理的区别

  • jdk动静代理实现了被代理类的接口,只能代理接口中的办法
  • cglib通过继承代理类实现,可代理所有办法,被final润饰的除外
  • Spring在创立代理类时,如果指标类有实现接口则应用jdk动静代理,否则应用cglib
5、(摘要)一个典型的动静代理创建对象过程可分为以下四个步骤:1、通过实现InvocationHandler接口创立本人的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(...);2、通过为Proxy类指定ClassLoader对象和一组interface创立动静代理类Class clazz = Proxy.getProxyClass(classLoader,new Class[]{...});3、通过反射机制获取动静代理类的构造函数,其参数类型是调用处理器接口类型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});4、通过构造函数创立代理类实例,此时需将调用处理器对象作为参数被传入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));为了简化对象创立过程,Proxy类中的newInstance办法封装了2~4,只需两步即可实现代理对象的创立。生成的ProxySubject继承Proxy类实现Subject接口,实现的Subject的办法理论调用处理器的invoke办法,而invoke办法利用反射调用的是被代理对象的的办法(Object result=method.invoke(proxied,args))

IOC容器的初始化过程

启动是通过AbstractApplicationContext的refresh()办法进行启动,具体来说,这个启动包含BeanDefinition的Resouce定位、载入和注册三个根本过程。

1、第一个过程是Resource定位过程
指对BeanDefinition的资源定位过程。由对立的ResourceLoader实现。Bean 可能定义在XML中,或者是一个注解,或者是其余模式,这些都被用Resource来定位, 读取Resource获取BeanDefinition

2、第二个过程是BeanDefinition的载入
这个载入过程是把用户定义好的Bean示意成IoC容器外部的数据结构,而这个容器外部的数据结构就是BeanDefinition。

3、第三个过程是向IoC容器注册这些BeanDefinition
这个过程把载入过程中解析失去的BeanDefinition向IoC容器进行注册。在IoC容器外部将BeanDefinition注入到一个ConcurrentHashMap中去。
这个ConcurrentHashMap是定义在DefaultListableBeanFactory中的beanDefinitionMap

/** Map of bean definition objects, keyed by bean name. */private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

Spring创立一个Bean的过程

1、实例化Bean
上面Spring Bean的生命周期前6点

2、将Bean注册到IOC容器
DefaultSingletonBeanRegistry中的singletonObjects

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

Spring Bean的生命周期

1、实例化Bean
当客户向容器申请一个尚未初始化的bean时,或初始化bean的时候须要注入另一个尚未初始化的依赖时,BeanFactory容器就会调用getBean办法尝试获取,如果Bean曾经被实例化则返回这个Bean,如果没有实例化,则调用createBean办法,通过反射创立(BeanUtils的instantiateClass办法)

2、设置对象属性
依赖注入,BeanWraper实现,通过递归的形式获取指标bean及其所依赖的bean

3、解决Aware接口
Spring会检测该对象是否实现了xxxAware接口,并将相干的xxxAware实例注入给Bean。

如果这个Bean曾经实现了BeanNameAware接口,会调用它实现的setBeanName(String beanId)办法,此处传递的就是Spring配置文件中Bean的id值;
如果这个Bean曾经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory()办法,传递的是Spring工厂本身。
如果这个Bean曾经实现了ApplicationContextAware接口,会调用setApplicationContext(applicationContext)办法,传入Spring上下文;

4、BeanPostProcessor前置解决
BeanPostProcessor是Spring提供的在Bean的初始化前后接管IOC容器回调的处理器,如果想对Bean进行一些自定义的解决,那么能够让Bean实现了BeanPostProcessor接口,那在Bean初始化前将会调用postProcessBeforeInitialization办法,在初始化后会调用postProcessAfterInitialization办法

5、InitializingBean 与 init-method
如果Bean实现了InitializingBean接口,将会执行重写的afterPropertiesSet办法
如果在xml中配置了init-method,则会执行指定的初始化办法

6、BeanPostProcessor后置解决

以上以上几个步骤实现后,Bean就曾经被正确创立了

7、DisposableBean
当Bean不再须要时,会通过清理阶段,如果Bean实现了DisposableBean这个接口,会调用其实现的destroy()办法;

8、destroy-method
最初,如果这个Bean的Spring配置中配置了destroy-method属性,会主动调用其配置的销毁办法。

怎么在Bean初始化的先后执行一段代码逻辑

1、通过实现 InitializingBean/DisposableBean 接口来定制初始化之后/销毁之前的操作方法
2、通过在xml中配置 init-method/destroy-method指定初始化之后 /销毁之前调用的操作方法
3、在指定办法上加上@PostConstruct 或@PreDestroy注解来制订该办法是在初始化之后还是销毁之前调用。

调用程序为:
Constructor > @PostConstruct > InitializingBean > init-method

Spring反对的几种bean的作用域

(1)singleton:默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory本身来保护。
(2)prototype:为每一个bean申请提供一个实例。
(3)request:为每一个网络申请创立一个实例,在申请实现当前,bean会生效并被垃圾回收器回收。
(4)session:与request范畴相似,确保每个session中有一个bean的实例,在session过期后,bean会随之生效。
(5)global-session:全局作用域,global-session和Portlet利用相干。当你的利用部署在Portlet容器中工作时,它蕴含很多portlet。如果你想要申明让所有的portlet共用全局的存储变量的话,那么这全局变量须要存储在global-session中。全局作用域与Servlet中的session作用域成果雷同。

循环依赖的解决办法

Spring在利用构造方法创建对象实例,还未设置对象属性前,会将实例的援用放入Spring的三级缓存singletonFactories中,在设置对象属性时,会先查看三级缓存中是否曾经存在

DefaultSingletonBeanRegistry类中的几个属性:

//一级缓存,寄存曾经实例化实现的对象/** 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);/** Set of registered singletons, containing the bean names in registration order. */private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

BeanFactory和ApplicationContext有什么区别

  • BeanFactory是Spring最底层的容器接口,定义了Bean工厂的很多根底性能,如读取bean配置文档,治理bean的加载,治理bean的申明周期,保护bean之间的依赖关系。
  • ApplicationContext继承了BeanFactory,并提供了一些扩大性能,如反对国际化、提供在监听器中注册bean事件等
  • 利用场合咱们个别间接应用ApplicationContext

怎么获取ApplicationContext与被Spring治理的Bean

实现ApplicationContextAware接口,实现该接口的setApplicationContext(ApplicationContext context)办法,并保留ApplicationContext 对象。Spring初始化时,会通过该办法将ApplicationContext对象注入。

public class SpringContextUtil implements ApplicationContextAware {   private static ApplicationContext applicationContext;  public void setApplicationContext(ApplicationContext applicationContext) {      SpringContextUtil.applicationContext = applicationContext;  } }

获取到ApplicationContext后通过applicationContext.getBean()办法获取bean。

Spring 框架中都用到了哪些设计模式?

1、工厂模式:BeanFactory就是简略工厂模式的体现,用来创建对象的实例;

2、单例模式:Bean默认为单例模式。

3、代理模式:Spring的AOP性能用到了JDK的动静代理和CGLIB字节码生成技术;

4、模板办法:比方 RestTemplate, JmsTemplate, JpaTemplate。用来解决代码反复的问题。

5、观察者模式:Spring中listener的实现--ApplicationListener

观察者模式:定义对象键一种一对多的依赖关系,当一个对象的状态产生扭转时,所有依赖于它的对象都会失去告诉被制动更新

6、责任链模式:SpringMVC中的拦截器应用责任链模式实现

SpringMVC

执行流程

1、用户发送申请,前端控制器DispatcherServlet依据匹配规定接管到申请

2、DispatcherServlet通过调用处理器映射器(HandlerMapping)、处理器适配器(HandlerAdapter)找到具体的处理器Controller

3、处理器调用业务逻辑组件解决业务逻辑,实现后,将返回一个逻辑视图ModelAndView对象给DispatcherSevlet

4、DispatcherSevlet通过视图解析器ViewResolver将逻辑视图转化为真正的视图,并返回给客户端

拦截器与过滤器的区别

  • 都是拦挡申请做一段逻辑解决
  • 过滤器是servlet级别的,个别用来设置全局匹配的url,设置编码格局等。拦截器是spring提供的组件和能力
  • 拦截器能够获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,能够调用业务逻辑。

Mybatis

Mybatis是一个对象关系映射框架,在配置文件中提供长久化类与数据库表的映射关系,框架在运行时参照映射文件中的信息,将对象长久化到数据库,或把从数据库查问进去的数据封装成对象。

次要有Configuration、SqlSessionFactory、SqlSession、Executor、StatementHandler等外围类

运行流程

1、程序启动时,Configuration读取配置文件中的元数据,动静配置mybatis的属性,并创立SqlSessionFactory对象

2、SqlSessionFactory对象中保留了以后数据库的配置信息和所有映射关系,保留了数据源的连接池

3、一条sql执行,会通过SqlSessionFactory创立一个会话对象SqlSession,并绑定一个数据库连贯

4、SqlSession会调用底下真正干活的执行器Executor

5、Executor负责Sql语句的动静生成,并调用手下的StatementHandler与JDBC的statement交互,并将获取到的数据由jdbc类型转换为java类型


Mybatis的一级缓存与二级缓存

1、一级缓存作用域为sqlSession,默认关上
2、二级缓存作用域为Mapper,默认敞开
3、分布式系统开启Mybatis缓存容易产生脏数据,个别用redis等分布式缓存代替
4、当某个作用域执行C/U/D操作后,缓存会被clear

SpringBoot

SpringBoot主动拆卸原理

1、SpringBoot通过main办法启动调用run()办法,run()办法会刷新容器,刷新容器时会去扫描classpath上面的包中的META-INF/spring.factories文件
2、这个文件中记录了很多主动配置类,在刷新容器时会将这些配置类加载到容器中,而后依据这些配置类中的条件注解,来判断是否将这些配置类在容器中进行实例化
3、这些判断条件次要是判断我的项目是否有相干jar包,或是否引入相干bean,这样SpringBoot就帮咱们实现了主动拆卸

@SpringBootApplication是一个复合注解,这个注解中有一个@EnableAutoConfiguration注解,这个注解就是开启主动配置,这个注解会引入一个AutoConfigurationImportSelector类,去扫描classpath上面的包中的META-INF/spring.factories文件