什么是Spring框架?
Spring是一种轻量级开发框架,旨在提高开发人员的开发效率以及系统的可维护性。
目的:解决企业应用开发的复杂性
功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
范围:任何Java应用
简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
Spring官网列出的Spring的6个特性:
核心技术,测试,数据访问,Web支持,继承,语言。
spring的理解?
Ioc控制反转是一种设计思想,就是由new对象变成外部提供对象,spring提供了个ioc容器.实现了ioc思想,IoC在其他语言中也有应用,并非Spring特有。IoC容器是Spring用来实现IoC的载体,IoC容器实际上就是个Map(key,value),Map中存放的是各种对象。IoC容器就像是一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件/注解即可,完全不用考虑对象是如何被创建出来的。DI依赖注入,让容器中的bean与bean产生联系,即classA需要classB的帮助,但是呢不去new对象,而是去ioc容器提供! aop面向切面编程,在原有不动的基础上进行增强.看过和简单写过他的底层,是动态代理机制,有jdk和cglib动态代理.再有接口的情况下是使用jdk代理.创建的代理对象实现目标对象的接口.没有接口呢,则是使用cglib代理,创建的代理对象是目标对象的子类. jdk代理是实现了invocationhandler接口,通过proxy的newProxyinstance方法创建代理对象. cglib是通过反射获取目标对象,然后enchanger对象去创建对象的子类.有参构造 ,spring底层满足扩展性
JDK动态代理总结:InvocationHandler +Proxy.newProxyInstance()。
InvocationHandler 是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类的方法,动态的将横切逻辑和业务逻辑编制在一起。 JDK动态代理要求被代理对象(接口实现类)通过反射注入到中间对象(JdkProxyFactory),且中间对象实现InvocationHandler 接口。重写invoke方法,invoke方法中编写增强代码。 Proxy.newProxyInstance()能利用中间对象(JdkProxyFactory)来生产代理对象。代理对象利用InvocationHandler接口动态创建一个符合某一接口的实例。 被代理的对象必须实现接口,而且只有接口中的方法才能被代理。
GCLIB动态代理总结:实现 MethodInterceptor接口,重写其 interceptor()方法 。
CGLib采用非常底层的字节码文件,可以为一个类创建子类,并在子类采用方法拦截的技术拦截所有父类方法的调用,并顺势植入横切逻辑。 继承被代理对象,然后重写被代理的方法,再覆盖该方法时,插入自己的代码,通过CglibMethodInvocation来启动配置的通知。 Enhancer .create创建代理对象。 因为需要重写被代理对象的方法,所以被代理的方法不能使final方法,因为final方法不能被覆盖。
8.1.2 列举一些重要的Spring模块
Spring Core可以说Spring其他所有的功能都需要依赖该类库。主要提供IoC依赖注入功能
Spring AOP: 提供面向切面的编程实现。
Spring JDBC: Java数据库连接。
Spring ORM: 用于支持Hibernate等ORM工具。
Spring Web:为创建Web应用程序提供支持。
Spring Test:提供了对Junit测试的支持。
bean的生命周期?
spring容器启动后,通过构造方法实例化bean,依赖属性注入,看实现了哪些Aware接口,调用接口方法.然后初始化init_method.使用bean,执行业务逻辑方法.最后调用spring容器的销毁方法destroy方法,销毁关闭bean
什么是bean?
被spring管理的对象; 经过一系列的生命周期方法处理之后的class就是bean对象.
Bean的含义:被Spring IOC容器初始化、装配、管理的对象。
什么是单例模式?
程序中只有一个对象的实例;即项目中需要这个bean的时候,返回的是唯一的bean
Spring的单例是基于BeanFatory也就是Spring容器的,单例Bean在此容器内只有一个,Java的单例是基于JVM,每个JVM中内只有一个实例。
spring的bean是单例的还是多例的?
spring中bean默认是单例的,如果要变成多例的,则使用scope属性,propotype变成多例的.单例是singleton;
为什么bean是单例的,单例和多例的区别?
默认是bean单例的,
快速的获取到bean,提升性能,减少jvm的损耗;但是单例线程是不安全的,多线程操作bean的时候则会出现线程安全.在bean对象中尽量避免定义可变的成员变量(不太现实).2.在类中定义一个ThreadLocal成员变量,将可变的成员变量保存在ThreagLocal;
@Component和@Bean的区别是什么?
1.作用对象不同:@Component注解作用于类,而@Bean注解作用于方法,因为这个方法返回的就是new 类。
2.@Component通常是通过类路径扫描来自动装配到Spring容器中(会调用ComponentScan注解去扫描路径)。@Bean告诉了Spring这是某个类的示例,当我们需要用它的时候就给我。
3.当我们要引用第三方库的类时,我们只能用@Bean
什么是自动装配?
在不用property和construtor-args时,spring通过在上下文查找,注入相对应的属性.
spring的三种功能注入方式?
注解,setter,构造器;
解释不同方式的自动装配
有五种自动装配的方式,可以用来指导Spring容器用自动装配方式来进行依赖注入。
-
no:默认的方式是不进行自动装配,通过显式设置ref 属性来进行装配。
-
byName:通过参数名 自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byname,之后容器试图匹配、装配和该bean的属性具有相同名字的bean。
-
byType::通过参数类型自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byType,之后容器试图匹配、装配和该bean的属性具有相同类型的bean。如果有多个bean符合条件,则抛出错误。
-
constructor:这个方式类似于byType, 但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。
-
autodetect:首先尝试使用constructor来自动装配,如果无法工作,则使用byType方式。
spring如何管理事务的?
spring是默认有事务的,但默认单条sql一个事务,只能读取最新值.管理事务有两中,一种编程式事务管理,一种声明式管理事务,编程式管理事务spring推荐的是TransactionTemplate,但是实际开发中常用的是声明式管理事务,使用注解@Transactional开启
Spring事务的隔离级别有哪几种?
TransactionDefinition接口中定义了五个表示隔离级别的常量(sql是4个+一个默认):
1.Default:使用后端数据库默认的隔离级别,Mysql默认采用的是可重复读。Sqlsever默认采用的是读已提交。
2—5与sql的四个事务一样:读未提交、读已提交、可重读、串行化。
什么是spring的容器?
applicationcontext 是spring的容器,class是加在xml,annoation的是spring配置类的字节码文件;
aop的组成?
aop:连接点,切入点,切面,通知,
aop工作流程?
spring容器启动,读取切面配置的切入点
spring常用的注解
@Component和他的三个衍生注解@Service业务处理的注解,@Resiporty和@Controller,springmvc里用到@RequestMapping方法路径,@RestController,rest风格的控制层返回给前端的都是json格式的数据.@Responsebody将返回值保存到请求体中返回给前端.@RequestBody将前端的json格式的数据转换为对象,@PathVariable从路径上获取参数.
单元测试启动spring容器:
applicationContext读取xml文件,或者springconfig配置类.或者配合junit注解启动@Runwith ,@ContextConfiguration
单元测试的时候怎么启动spring容器的?
这个可以通过读取配置文件的方式也行,用applicationContext读取xml配置文件,其实我更喜欢使用Spring配合junit用注解的方式去启动
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:spring-config-test.xml"})
spring的三个缓存?
一级缓存是存放初始化后的bean
二级缓存,是存放未完成注入的bean
三级缓存,是存放刚创建出来的bean,存放实例化完成的bean工厂类 (三级缓存解决循环依赖;)
存放已经创建完成,但是还没有注入好的对象的工厂对象,通过这个工厂可以返回这个对象
gav:maven坐标的意思(G:groupid,A:artifactId ,V:version); oop:面向对象编程; orm: 对象关系映射; soa:面向服务架构; npe:空指针异常; oom:jvm内存溢出;
springmvc
springmvc的理解?
springmvc是依据mvc三层软件设计思想,把controller层单独解耦出来,对web层单独进行优化开发,之前的项目中呢,一个功能对应一个servlet,代码繁琐.springmvc就提供了一个disipacherServlet前端控制器集中统一处理,根据不同的功能对应不同的方法.
异常在那一层抛出?
所有异常都在表现层抛出;
序列化接口的主要目的?
是为了让对象可以被序列化,将对象流化,把对象转换成字节流,便于在网络上进行传输或持久化操作.
怎么获取dao层接口的对象?
是有spring整合mybatis,中mapperScannercofigurer.这个类会通过basepackage扫描对应包下的接口,创建其代理类.通过jdk动态代理模式.
spring整合mybatis
初始化类型别名,,初始化datasources.初始化映射配置
@ResponseBody和@RequestBody有什么区别?
responseBody的作用是将返回值转换成JSON格式保存到响应体中返回给前端. requestbody的作用是将前端传过来的JSON格式的数据转换成相应的对象
为什么springmvc只扫描controller层,spring扫描dao和service层?
因为处理器映射器只会去SpringMVC中查找到Controller,如果没有,就找不到,不会去Spring中找,这就决定了,Controller必须在SpringMVC中扫描
springmvc扫描controller层单独处理,如果扫描了service和dao层那么就没有默认事务管理了,因为service中的事务在spring的管理下.spring扫描controller的话,项目运行找不到controller对应的路径,会报404错;
springmvc的执行流程?
客户端向服务器发送请求,请求被DispatcherServlet拦截,由DispatcherServlet将提交的信息交给处理器映射器,处理器映射器根据请求的路径找到对应给Controller进行处理,Controler调用Service层进行业务处理,并将处理结果封装到ModelAndView对象中,前段控制器将modelandview对象进行解析,并将返回的view进行渲染,最后将渲染结果返回给客户端
SpringMVC的启动服务器初始化过程和单次请求过程?
服务器启动,执行ServletContainersInitConfig类,初始化web容器 执行createServletApplicationContext方法,创建了WebApplicationContext对象 加载SpringMvcConfig 执行@ComponentScan加载对应的bean 加载UserController,每个@RequestMapping的名称对应一个具体的方法 执行getServletMappings方法,定义所有的请求都通过SpringMVC
发送请求localhost/save web容器发现所有请求都经过SpringMVC,将请求交给SpringMVC处理 解析请求路径/save 由/save匹配执行对应的方法save() 执行save() 检测到有@ResponseBody直接将save()方法的返回值作为响应体返回给请求方
springmvc如何处理post乱码?
为web容器加上过滤器,指定编码为utf-8,spring-web包中提供了专门的过滤器;
SpringMVC的Controller的成员变量?
Java里有个API叫做ThreadLocal,spring单例模式下用它来切换不同线程之间的参数。用ThreadLocal是为了保证线程安全,实际上ThreadLoacal的key就是当前线程的Thread实例。单例模式下,spring把每个线程可能存在线程安全问题的参数值放进了ThreadLocal。这样虽然是一个实例在操作,但是不同线程下的数据互相之间都是隔离的,因为运行时创建和销毁的bean大大减少了,所以大多数场景下这种方式对内存资源的消耗较少,而且并发越高优势越明显。 总的来说就是,单利模式因为大大节省了实例的创建和销毁,有利于提高性能,而ThreadLocal用来保证线程安全性。另外补充说一句,单例模式是spring推荐的配置,它在高并发下能极大的节省资源,提高服务抗压能力。spring IOC的bean管理器是“绝对的线程安全”。比如说Thread A处理一个任务时,它的ThreadLocal里保存了一个变量,处理完任务后Thread A放到线程池里。 高并发情况下,如果另一个请求分配给Thread A处理时,它的ThreadLocal在上次保存的变量会不会影响这次的处理呢? 所以说,spring的注解排上用场了@Scope(value="request")
SpringMVC中的拦截器和Servlet的过滤器有什么区别?
Servlet的过滤器是在springMVC的拦截器之前运行的
①拦截器是基于Java的反射机制的,而过滤器是基于函数回调。 ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。 ③拦截器只能对部分请求起作用,而过滤器则可以对几乎所有的请求起作用。 ④拦截器可以访问spring容器上下文、值栈里的对象,而过滤器不能访问。 ⑤在controller的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。 ⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
Controller, RestController区别?
@Controller:标识一个Spring类是Spring MVC controller处理器,@RestController:@RestController是@Controller和@ResponseBody的结合体,两个标注合并起来的作用。@Controller类中的方法可以直接通过返回String跳转到jsp、ftl、html等模版页面。这个情况属于比较传统的Spring MVC的应用,对应于前后端不分离的情况。@RestController类中的所有方法只能返回String、Object、Json等实体对象,不能跳转到模版页面。@RestController中的方法如果想跳转页面,则用ModelAndView进行封装; Controller, RestController的共同点都是用来表示Spring某个类的是否可以接收HTTP请求。
MVC流程,@RequestMapping的注解具体怎么实现的?
1.Spring扫描所有的Bean
2.遍历这些bean,依次判断是否是处理器,并检测其HandlerMethod
3.遍历Handler中的所有方法,找出其中被@RequestMapping注解标记的方法。
4.获取方法method上的@RequestMapping实例
5.检查方法所属的类有没有@RequestMapping注解
6.将类和方法的RequestMapping结合
7.当请求到达时,去UrlMap中找匹配的Url,以及获取对应mapping实例,然后去handerMethods中获取匹配HandlerMethod实例。
8.将RequestMappingInfo实例以及处理方法注册到缓存中。
springboot
springboot的理解?
springboot是基于spring框架基础上提供了一个全新的框架,简化了spring的基本配置和开发过程,springboot遵循约定大于配置的原则,只需要少量的配置或者使用默认配置就行,springboot的自动配置解决了spring程序的配置繁琐,通过@EnableAutoConfigrition注解开启自动配置,加载spring.factory文件下的AutoConfigution类,如果满足@Condition的指定条件时,则加载其对应的组件,注入到spring的容器中,完成了自动配置,然后springboot也提供了起步依赖,也就是提供了各种starts启动器,比如想加载个springmvc的web应用程序,只需要配置spring-boot-start-web依赖就行,maven会自动加载所需要的依赖项,和springmvc的框架以及相关的库,开箱即用;springboot提供内嵌的tomcat,jetty,等servlet容器,不用再需要单独的web服务器
springboot,基于spring的基础上的一个全新的框架,简化了spring的基本配置和开发过程;
-
遵循“约定大于配置”的原则,使用 Spring Boot 只需很少的配置或者使用基本的默认配置。
-
约定大于配置开发中有些东西我们没有去配置,程序会使用的默认的配置.
-
提供 很多的Starters(启动器),简化 Maven ,避免依赖冲突。
-
提供内嵌 Servlet 容器,可选择内嵌 Tomcat、Jetty 等容器,不需要单独的 Web 服务器
springboot的三个注解?
@SpringBootConfiguration:标记当前类为配置类 @EnableAutoConfiuration:开启自动配置 @ComponentScan:扫描主类所在包及其子包、同级包中的Bean
1.@springbootConfiguration
用来代替 applicationContext.xml 配置文件,所有这个配置文件里面能做到的事情都可以通过这个注解所在类来进行注册。
2.@ComponentScan
用来代替配置文件中的 component-scan 配置,开启组件扫描,即自动扫描包路径下的 @Component 注解进行注册 bean 实例到 context 中。
3.@EnableAutoConfiguration
用来提供自动配置
什么是springboot自动配置?
解决 Spring 程序配置繁琐的问题
Springboot是通过@EnableAutoConfiguration注解开启自动配置的,对spring-boot-autoconfigure.jar包下的spring.factories这个文件进行扫描,这个文件包含了可以自动装配的类,当满足@Condition注解指定的条件时,便在依赖的支持下进行实例化,注册到Spring容器中。(有反射)
什么是springboot起步依赖?
起步依赖就是各种starter(启动器),解决了spring程序依赖设置繁琐的问题;解决版本冲突,简化了依赖设置;如果你想创建一个使用Spring MVC框架的Web应用程序,只需添加spring-boot-starter-web启动器依赖项到项目的构建配置文件中。添加完成后,Maven会自动下载并引入所需的所有依赖项,包括Spring MVC框架和其他相关库。
SpringBoot配置文件有几种?优先级是什么?配置文件不同位置优先级有区别吗?
有三种,properties>yml>yaml, 1级 在jar包的外部的 config/application.yml 2级 在jar包的外部的 application.yml 3级 在jar包内的 config/application.yml 4级 在jar包内的 application.yml
补充知识
雪花算法:
64位bite的long类型的id.
1位固定位.o 41位时间戳,69年 10位机器工号.1024 12位序列号 4096个
整合spring和springmvc?
Spring容器是一个父容器,SpringMVC容器是一个子容器,它继承自Spring容器。因此,在SpringMVC容器中,可以访问到Spring容器中定义的Bean,而在Spring容器中,无法访问SpringMVC容器中定义的Bean。在Web开发中,Controller全部在SpringMVC中扫描,除了Controller之外的Bean,全部在Spring容器中扫描(Service、Dao),按这种方式扫描,扫描完完成后,Controller可以访问到Service。
事务的传播特性:
当一个事务方法被另一个事务方法调用的时候,应该怎么调处理,(一起成功或者一起失败)
7种传播特性:
required:支持当前事务,如果不存在就新建一个;(默认)
requires_new:开始一个新的事务,如果一个事务已经存在,则将这个存在的事务挂起;
supports:支持当前事务,如果当前没有事务,则以非事务方式执行;
not_supported:以非事务的方式运行,如果有事务存在,挂起当前事务;
mandatory:必须运行在一个事务中,如果当前没有事务发生,则抛出一个异常:
never:以非事务的方式运行,如果事务存在,抛出异常;
nested:如果当前正有一个事务在进行中,则该方法应当运行在一个嵌套式事务中。被嵌套的事务可以独立于封装事务进行提交或回滚。如果封装事务不存在,如果封装事务不存在,行为就跟required默认的一样;;
SpringBoot和SpringMVC与SpringCloud关系?
\1. Spring 框架就像一个家族,有众多衍生产品例如 boot、security、jpa等等。但他们的基础都是Spring的ioc、aop等. ioc 提供了依赖注入的容器, aop解决了面向横切面编程,然后在此两者的基础上实现了其他延伸产品的高级功能;
\2. springMvc主要解决WEB开发的问题,是基于Servlet 的一个MVC框架,通过XML配置,统一开发前端视图和后端逻辑;
\3. 由于Spring的配置非常复杂,各种XML、JavaConfig、servlet处理起来比较繁琐,为了简化开发者的使用,从而创造性地推出了springBoot框架,默认优于配置,简化了springMvc的配置流程;但区别于springMvc的是,springBoot专注于单体微服务接口开发,和前端解耦,虽然springBoot也可以做成springMvc前后台一起开发,但是这就有点不符合springBoot框架的初衷了;
\4. 对于springCloud框架来说,它和springBoot一样,注重的是微服务的开发,但是springCloud更关注的是全局微服务接口的整合和管理,相当于管理多个springBoot框架的单体微服务;
Spring、SpringMVC、SpringBoot、SpringCloud的联系与区别
Spring:一个轻量级的控制反转和面向切面的容器。
SpringMVC: MVC 框架提供了模型-视图-控制的体系结构和可以用来开发灵活、松散耦合的 web 应用程序的组件
SpringBoot: 它基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决。
SpringCloud: 它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
联系与区别:Spring提供IOC和AOP的容器,并具有强大的扩展功能;Springmvc在上面拓展了WEB开发,基于Servlet的一个MVC框架,通过XML配置,统一开发前端视图和后端逻辑;SpringBoot专注于微服务方面的接口开发,和前端解耦,同时也解决了Spring配置非常复杂,各种XML、Servlet处理起来比较繁琐,默认优于配置,简化了SpringMVC的配置流程;SpringCould更关注全局微服务的整合和管理,相当于管理多个springBoot框架的单体微服务。
方库:
一方库: 本工程内部子项目模块依赖的库(jar 包)。 二方库: 公司内部发布到中央仓库,可供公司内部其它应用依赖的库(jar 包)。 三方库: 公司之外的开源库(jar 包)。
jar包跟war包的区别?
jar包时java程序压缩的包,是一些已经写好的类.引入到项目的话,可以直接使用
war 包就是 web 项目压缩包。war 是一个可以直接运行的 web 模块,一个 war 包可以理解成就是一个 web 项目
实例化是什么?
实例化就是用类创建对象的过程就是实例化
代理模式:
静态代理模式的好处:
-
可以使真实觉得的操作更加纯粹!不用关注一些公共的业务
-
公共也就是交给代理角色!实现了业务的分工!
-
公共业务发生扩展的时候,方便集中管理。
缺点:
-
一个真实角色就会产生一个代理角色;代码量会翻倍~开发效率会变低~
动态代理的好处:
-
可以使真实觉得的操作更加纯粹!不用关注一些公共的业务
-
公共也就是交给代理角色!实现了业务的分工!
-
公共业务发生扩展的时候,方便集中管理。
-
一个动态代理类就是一个接口,一般就是对应的一类业务
-
一个动态代理类可以代理多个类多个类,只要是实现了同一个接口即可。
Spring框架中用到了那些设计模式?
工厂设计模式:Spring使用工厂模式通过BeanFactory、ApplicationContext创建bean对象。
代理模式:Spring AOP功能的实现。
单例设计模式:Spring中的Bean默认都是单例的。
包装器设计模式:我们的项目需要连接不同类型的数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们根据客户的需求能够动态切换不同的数据源。
观察者模式:Spring事件驱动模型就是观察者模式最经典的一个应用。
适配器模式:SpringAOP的增强或通知(Advice)使用到了适配器模式、Spring MVC中也是使用了适配器模式适配Controller。 加一个适配器的类,引入网线,转成USB,这样电脑用USB就可以上网了。