Spring 的特性是什么?IOC和AOP的原理是什么?AOP的注解有哪些?
特性:方便解耦,简化开发;AOP编程的支持;声明事务的支持;方便程序的测试;方便集成各种优秀框架;降低Java EE API的使用难度;Java源码的经典学习范例
IOC和AOP原理:
IOC,控制反转是面向对象编程中的一种设计原则,基于java的反射机制以及工厂模式实现的,主要是协调各组件相互的依赖关系,同时大大提高了组件的可以移植性,用来减低代码之间的耦合度
原理:由容器控制程序之间的关系,而非传统现实中,由程序代码直接操控说白了就是由Spring容器来实现对象的统一管理工作,我们只需要关心 业务逻辑本身就可以了
AOP:面向切面编程,通过预编译方式和运行期动态实现程序功能的统一维护的一种技术,主要是使用动态代理实现的
原理:一是采用动态代理技术,利用截取消息的方式,对该消息进行封装,以取代原有的对象执行;二是采用静态织入的方法,需要引入特定的语法创建"方面",在编译期织入有关"方面"的代码,属于静态代理
AOP的注解:
@Before 前置通知,在方法执行之前执行
@After 后置通知,在方法执行之后执行
@AfterRunning 返回通知,在方法正常结束后,返回结果之后执行,可以访问方法的返回值
@AfterThrowing 异常通知,在方法抛出异常之后
@Around 环绕通知,围绕方法执行
SpringBoot自动装配的原理是什么?
@SpringBootApplication注解,SpringBoot的这个注解应用在哪个类上就说明这个类是主配置类
@SpringBootApplication是一个组合注解,是由@SpringBootConfiguration、@ComponentScan、@EnableAutoConfiguration三个注解组成的
@SpringBootConfiguration这个注解实际上就是代表了一个配置类,相当于一个beans.xml文件;
@ComponentScan的功能就是自动扫描并加载符合条件的组件或bean,最终将这些bean加载到容器中
@EnableAutoConfiguration代表开启SpringBoot的自动装配,原理是借助@Import的帮助,将符合自动配置条件的bean加载到IOC容器中,从而实现自动装配。
SpringBoot项目如何打包、部署、运行
SpringBoot的打包方式有很多种,最常见的war和jar,因为SpringBoot是前后端分离的项目,所以jar进行部署更合适
首先要在配置文件中配置端口,数据库连接等
在主启动类上加上extends SpringBootServletInitializer(想当于web.xml)并重写configure方法,这是为了打包springboot项目以及在web容器运行用的
Spring是如何控制事务的
spring控制事务有两种,一是编程式事务控制,二是声明式事务控制
编程式事务控制即通过编写代码的方式实现事务的控制
声明式事务控制
可以基于@Transactional注解的声明式事务控制,但使用@Transactional注解需要在配置文件中开启对这个注解的扫描
使用AOP的声明式事务控制,需要配置事务增强;配置事务增强方法的传播行为;配置切点和对应的事务通知
基于TransactionProxyFactoryBean代理的声明式事务控制
SpringMVC常用注解及作用
@Controller:标注一个控制器组件类,声明该类是SpringMVC的Controller
@RestController:该注解里面包含了Controller注解和ResponseBody注解
@Component:标注一个普通的Spring bean类
@Service: 标注是一个业务层组件类
@RequestMapping:该注解是建立请求的URL和处理方法之间的对应关系,可以作用在方法和类上
@Autowried:该注解可以对类成员、方法以及构造函数进行标注,完成自动装配的工作,该注解是根据类型进行自动装配的,通过该注解来消除 set,get方法。
@ResponseBody:该注解通常使用在控制层的方法上,用于将Controller的方法返回的对象,通过springmvc提供的接口转换为指定格式的数据,通过Response响应给客户端
@PathVariable该注解主要用来获取URL参数,支持Restfull风格的URL
@RequestParam注解是用来传递参数的,用于将请求参数数据映射到功能处理方法的参数上
@RequestBody该注解作用于获取请求体的内容
SpringMVC的工作流程
用户发送HTTP请求;
请求进入前端控制器DispatcherServlet
前端控制器调用处理器映射器HandlerMapping组件根据请求找映射的Controller处理
执行Controller处理方法,将返回结果给视图解析器ViewResolver组件
视图解析器根据Controller返回的结果将模型数据传递给前端
前端生成一个结果给客户端
Mybatis的工作原理是什么?Mybatis的缓存的理解
Mybatis的工作原理:
读取Mybatis配置文件
加载映射文件
构造会话工厂SqlSessionFactory
创建会话对象SqlSession完成和数据库的交互
定义Executor执行器接口来操作数据库
MappedStatement对象封装映射信息
输入参数映射
输出参数映射
Mybatis缓存的理解:
Mybatis有一级缓存和二级缓存,默认情况下一级缓存是开启,而且不能关闭
一级缓存是指SqlSession级别的缓存,当在同一个SqlSession中进行相同的SQL语句查询时,第二次以后的查询不会从数据库查询,二是直接从缓存中获取,一级缓存最大能缓存1024条SQL
二级缓存是指可以跨SqlSession的缓存,是mapper级别的缓存,对于mapper级别的缓存不同的session是可以共享的;二级缓存需要在全局配置中开启二级缓存配置,在对应的mapper.xml中配置cache节点,在对应的select查询节点中添加的useCache=true
Mybatis中#{}和${}的区别?
mybatis在处理#{},会将sql中的#{}替换为?,调用PreparedStatement的set方法来赋值;
mybatis在处理 {}时,就是把时,就是把{}替换成变量的值
{}是预编译处理,${}是字符串替换
预编译语句的优势:一次编译、多次运行,省去了解析优化等过程;还能防止sql注入
使用#{}可以有效的防止SQL注入,提高系统安全性
SpringBoot的异常处理的五种方式?
自定义异常错误页面--默认的异常处理机制
使用@ExceptionHandler注解处理局部异常--单个使用该注解方法的Controller异常
使用@ControllerAdive+@ExceptionHandler注解处理全局异常--根据不同的异常对不同的异常进行处理
配置SimpleMappingExceptionResolver类处理异常--通过将类注入到Spring容器中实现全局范围处理异常
实现HandlerExceptionResolver接口处理异常
Spring中如何配置过滤器、拦截器
过滤器(Filter):
过滤器是Servlet中的一个组件,在Servlet之前执行,由于执行时机比Servlet要早,所以可以用来做一些过滤验证,
自定义过滤器先写一个类实现Filter
接口,重写init(),doFilter(),destroy()。
其中init()是完成Filter的初始化,
doFilter()是过滤逻辑的方法,
destroy()是销毁过滤器方法。
拦截器(Intercefptor):
拦截器是Spring框架定义的组件,Spring的处理器支持连接器应用,前端控制器在调用处理器之前,如果有拦截器存在,就会先调用拦截器然后在调用处理器可以用来进行身份验证
自定义拦截器:先写一个类实现HandlerInterceptor接口,将拦截处理逻辑写在响应的接口方法里,重写preHandle(),postHandle(),afterCompletion(),
其中proHandle()在进入controller的方法执行之前,如果返回值是true,则继续使用拦截器,反之拦截器不再向后调用,请求处理完成;
postHandle()处理器方法已经执行完成,正准备将ModelAndView对象返回给前端控制器之前执行。可以在该方法里面,修改ModelAndView对象。
afterCompletion()最后执行的方法,需要当前的preHandle()的返回值为true是才会执行,适用于清理资源的,返回值为false,该方法不会执行。
spring管理的bean是否会存在并发?
Spring bean是线程不安全的,一般情况下,只有无状态的bean才可以在多线程环境下共享,单例模式下的bean应该是无状态的bean,不然可能会造成多线程并发修改状态的问题
对于有状态的bean解决方案:
scope="prototype"
ThreadLocal处理,ThreadLocal相当于一个成员变量,是线程安全的成员变量,每一个线程都保存一份,另外通过ThreadLocal比synchronized效率高,ThreadLocal是以空间换时间,synchronized是以时间换空间
代码控制同步,比如加锁
Spring session的原理是什么?
Spring session的原理是通过实现Filter创建过滤器SessionRepositoryFilter,在收到请求时采用装饰器模式重新分装HttpServletRequest和HttpServletResponse传递给FilterChain,之后对session的操作都交由SessionRepositoryRequestWrapper和SessionRepositoryResponseWrapper进行执行,以此来代理容器的session操作.
spring的类加载器是什么?
ClassLoader类就是根据一个指定的类的全限定名,找到对应的Class字节码文件,然后加载它转化成一个Class类的实例
BootStrap ClassLoader:称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库
Extension ClassLoader:称为扩展类加载器,负责加载Java的扩展类库
App ClassLoader:称为系统类加载器,负责加载应用程序classpath目录下的所有jar和class文件
SpringCloud的组件有哪些?作用分别是什么?
Dubbo和SpringCloud的区别和优缺点?
dubbo只是一个远程调用(RPC)框架,默认基于长连接,支持多种序列化格式
SpringCloud是一个框架集,提供了一整套微服务解决方案(全家桶)
dubbo是二进制的传输,占用带宽会更少
springcloud是http协议传输,带宽比较大,同时使用http协议一般是使用JSON报文,消耗会很大
dubbo的开发难度大,原因是dubbo的jar包依赖问题很多大型工程无法解决
springcloud的接口协议约定比较自由切松散,需要强有力的行政措施来限制接口无序升级
dubbo的注册中心可以选择zookeeper,redis等,springcloud的注册中心用eureka,consul
Gateway的动态路由如何实现?
默认情况下Gateway会根据注册中心注册的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
基于YML,properties从配置文件中读取路由信息,
基于redis,配置中心从存储器中读取路由信息,
基于Nacos,Eureka,zookeeper从注册中心中读取路由信息
实现动态路由的数据加载:
创建一个类,继承RouteDefinitionRepository实现自己获取的路由信息
自定义一个路由操作类DynamicRouteConfig,
进行主动推送事件进行刷新,实时发送RefreshRoutesEvent事件
保存到数据库,使用消息广播的方式通知各个gateway服务器实例调用notify()方法刷新路由信息.
鉴权框架的了解和使用
鉴权框架是指验证用户是否拥有访问系统的权利,
常用的有shiro框架,首先需要添加shiro框架的依赖,在添加安全数据源shiro-permission.ini文件,
然后获取securityFactory工厂类,继而获取安全管理器对象,在设置subjectManager对象,
把subject对象交给SecurityUtils管理,获取subject对象,生成token,进行验证,登录,然后用户授权
使用check方式检查授权,未授权直接报错,最后在使用permission方式检查权限.
Mybatis同时操作同一条数据该怎么解决并发问题
乐观锁,大多是基于数据版本记录机制实现的,就是为数据增加一个版本标识,在基于数据库的版本解决方案中,一般是通过数据库表增加一个"version"字段来实现的.
读取出数据时,将版本号一同读出,更新时,对版本进行加一,将提交数据的版本数据与数据库表对应记录当前版本信息进行比对,如果提交的数据版本号大于数据库表当前版本号,则可以更新,否则就是过期数据
Mybatis中传递参数的方式?
方式一:顺序传递参数
方式二:注解@Param传递参数
方式三:使用Map集合传递参数
方式四:使用JavaBean实体类传递参数
spring中bean的生命周期?作用域有哪些?
bean的生命周期:
bean的定义--bean的初始化--bean的使用--bean的销毁
bean的定义:
bean是spring装配的组件模型,一切实体类都可以配置成一个Bean,进而就可以在任何其他的bean中使用,一个bean也可以不是指定的实体类
bean的初始化:
bean的初始化回调有两种
一种是在配置文件中声明init-method="init",然后在一个实体类中用init()方法来初始化
另一种是实现InitializingBean接口,覆盖afterPropertiesSet()方法.
bean 的使用:
spring中有两种使用bean的方法:
BeanFactory:是延迟加载,如果bean的某一属性没有注入,加载后,直至第一次使用getBean方法才会抛出异常,就是说BeanFactory实例化对象时,配置的bean不会马上被实例化,当使用该bean时才会被实例化
ApplicationContext:该方法不管你用还是不用,都会被实例化,它是在初始化自身时检验,这样有利于检查所依赖属性是否注入,ApplicationContext是BeanFactory的子类,除了具有BeanFactory的所有功能外还提供了更完整的框架功能.
bean的销毁
bean的销毁和初始化一样,都是提供两个方法
一是在配置文件中声明destroy-method="cleanup",然后在类中写一个cleanup()方法销毁
二是实现DisposableBean接口,覆盖destory()方法
Spring可以管理simngleton作用域的bean的生命周期,所以在bean初始化以销毁之前可以做一些工作,更灵活的管理bean.
bean的作用域:
怎么实现mybatis批量插入
方法一:xml配置
mapper.xml中insert标签加上foreach标签用来测试批量插入的数据和服务层.
mapper.xml中插入语句写成一次性插入一个1000的列表listmapper.xml
方法二:注解
MyBatis提供用于插入数据的注解有两个:@insert,@InsertProvider
作用:用来在实体类的Mapper类里注解保存方法的SQL语句
工厂模式如何使用?
工厂模式:主要用于创建对象进行解耦,开发者并不需要使用new来创建一个对象,而是使用一个共同的接口类来制定其实现类,大大降低系统的耦合性,好处就是开发者获取对象简单,它封装了创建对象的逻辑;易于扩展;不影响调用者.
定义一个用于创建对象的接口,让子类决定具体实例化哪一个类,使类的实例化延迟到子类
通过读取配置文件来获取创建的对象全限定类名
通过反射来创建对象,尽量避免使用new关键字
springboot中starter种类有哪些?
spring-boot-starter: 核心Starter包含auto_configuration、日志和YAML
spring-boot-starter-cache: 启用Spring框架的缓存功能
spring-boot-starter-jdbc: 使用Tomcat JDBC连接池来使用JDBC
spring-boot-starter-thymeleaf: 在MVC应用中使用Trymeleaf视图
spring-boot-starter-web: 使用Spring MVC来构建RESTful Web应用,并使用Tomcat作为默认内嵌容器
如何写一个springboot的Starter组件?
starter的组件就是自动装配
引入spring-boot-autoconfigure依赖
创建配置实体类
创建自动配置类,设置实例化条件
在MATE-INF文件夹下创建spring.factories文件夹,激活自动配置
在maven仓库发布starter
设计一个开放接口,如何保证接口安全性?
客户端通过用户密码登录服务器并获取token
客户端生成时间戳timestamp,并将timestamp作为其中一个参数
客户端将所有的参数,包括token和timestamp按照自己的算法进行排序加密得到签名sign
将token,timestamp和sign作为请求时必须携带的参数加在每个请求的URL后边
服务器写一个过滤器对token,timestamp和sign进行验证,只有在token有效,timestamp未超时,缓存服务器中不存在sign三种情况同时满足,本次请求才有效.