JavaEE框架知识

技术的选型?为什么要分为SSM和Springboot开发?

什么是Spring Boot?
从本质上来说,Spring Boot就是Spring,它做了那些没有它你也会去做的Spring Bean配置。

SpringBoot的作用?

它使用“约定优于配置”(项目中存在大量的配置,此外还内置了一个习惯性的配置,让你无需手动进行配置)的理念让你的项目快速运行起来。使 用Spring
Boot很容易创建一个独立运行(运行jar,内嵌Servlet容器)、准生产级别的基于Spring框架的项目,使用Spring Boot你可以不用或者只需要很少的Spring配置。

SpringBoot的优点?
Spring由于其繁琐的配置,一度被人认为“配置地狱”,各种XML、Annotation配置,让人眼花缭乱,而且如果出错了也很难找出原因。
SpringBoot帮助开发者快速启动一个Web容器;
SpringBoot继承了原有Spring框架的优秀基因;
SpringBoot简化了使用Spring的过程。
SpringBoot的缺点?

Spring Boot作为一个微框架,离微服务的实现还是有距离的。没有提供相应的服务发现和注册的配套功能,自身的acturator所提供的监控功能,也需要与现有的监控对接。没有配套的安全管控方案,对于REST的落地,还需要自行结合实际进行URI的规范化工作。

什么是SSM?

SSM(Spring+SpringMVC+MyBatis)框架集由Spring、SpringMVC、MyBatis三个开源框架整合而成,常作为数据源较简单的web项目的框架。
其中spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
SpringMVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。
MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。
SSM有什么用?

SpringMVC:

1.客户端发送请求到DispacherServlet(分发器)

2.由DispacherServlet控制器查询HanderMapping,找到处理请求的Controller

3.Controller调用业务逻辑处理后,返回ModelAndView

4.DispacherSerclet查询视图解析器,找到ModelAndView指定的视图

5.视图负责将结果显示到客户端

Spring:
我们平时开发接触最多的估计就是IOC容器,它可以装载bean(也就是我们Java中的类,当然也包括service dao里面的),有了这个机制,我们就不用在每次使用这个类的时候为它初始化,很少看到关键字new。另外spring的aop,事务管理等等都是我们经常用到的。
?

Mybatis:
mybatis是对jdbc的封装,它让数据库底层操作变的透明。mybatis的操作都是围绕一个sqlSessionFactory实例展开的。mybatis通过配置文件关联到各实体类的Mapper文件,Mapper文件中配置了每个类对数据库所需进行的sql语句映射。在每次与数据库交互时,通过sqlSessionFactory拿到一个sqlSession,再执行sql命令。

SSM的优缺点?

1)spring 不说了,核心ioc、aop技术,ioc解耦,使得代码复用,可维护性大幅度提升,aop提供切面编程,同样的增强了生产力。

2)spring mvc嘛,是对比struts2等mvc框架来说的,不说struts2爆出的那么多安全漏洞,而且是类拦截,所有Action变量共享,同时是filter入口的,而spring mvc是方法拦截,controller独享request response数据,采用的serlvet入口,与spring无缝对接。开发而言,spring mvc更加轻量和低入门。

3)mybatis嘛,看业务场景,主要是mybatis的sql可以由开发者去掌控和调优,相对hibernate等orm框架来说,更加直观。在业务场景比较复杂,sql好多联合关联的情况下,mybatis谁用谁知道。当然缺点就是对sql不熟悉的开发者就不太友好了。

二者相比较优缺点?

SSM框架和spring boot全家桶相比有哪些优缺点?
这两者对比起来有点奇怪。因为SSM是WEB应用框架,涵盖整个应用层,而spring boot你可以看做一个启动、配置、快速开发的辅助框架,本身针对的是微服务。

springboot 只是为了提高开发效率,是为了提升生产力的:
1、springboot一个应用是一个可执行jar(启动类main方法启动web应用),而不像传统的war,内嵌tomcat容器,可以jar形式启动一个服务,可以快速部署发布web服务,微服务最好不过了。
2、将原有的xml配置,简化为java配置
3、当然结构可能跟一般的ssm有一定区别,但其实主要是在资源文件。

为什么要使用resulltf接口开发?

前后端分离,减少流量
安全问题集中在接口上,由于接受json格式,防止了注入型等安全问题
前端无关化,后端只负责数据处理,前端表现方式可以是任何前端语言(android,ios,html5)
前端和后端人员更加专注于各自开发,只需接口文档便可完成前后端交互,无需过多相互了解
服务器性能优化:由于前端是静态页面,通过nginx便可获取,服务器主要压力放在了接口上

讲一下Nginx的负载均衡、反向代理与正向代理,如何动静分离?

负载均衡:

在nginx的配置文件中进行负载均衡的配置
均衡策略:
轮询(默认)
权重、ip_hash

反向代理:
客户端不知道真正的目的主机地址,只知道域名,代理服务器会将请求转发给内网的一个服务器,这对客户端来说是透明的
使用nginx反向代理,访问 www.123.com 直接跳转到127.0.0.1:8080
通过修改本地 host 文件,将 www.123.com 映射到 192.168.137.129
正向代理:
客户端知道要访问的目的主机地址,但是无法直接访问,通过中间代理服务器代理后可以访问
动静分离:
严格意义上说应该是动态请求跟静态请求分开,可以理解成使用Nginx 处理静态页面,Tomcat处理动态页面
一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案;
另外一种方法就是动态跟静态文件混合在一起发布,通过 nginx 来分开。
通过 location 指定不同的后缀名实现不同的请求转发。
通过 expires 参数设置,可以使浏览器缓存过期时间,减少与服务器之前的请求和流量。

讲一下springAOP的实现原理与IOC

IOC:
将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注入。
Aop:
AOP(Aspect-Oriented Programming:面向切面编程) 能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

  1. 概述
    SpringAOP(Aspect Orient Programming)是一种设计思想,称为面向切面编程,利用横切技术剖析对象内部,将业务之间共同调用的逻辑提取并封装为一个可复用的模块,这个模块被命名为切面(Aspect),该模块减少系统中的重复代码,降低模块间的耦合度,可用于日志、权限认证、事务管理等。
    SpringAOP思想的实现一般都是基于代理模式 ,在Java中采用JDK动态代理模式,但是JDK动态代理模式只能代理接口而不能代理类。因此SpringAOP会在CGLIB、JDK动态代理之间进行切换。

代理类型

SpringAOP的实现是基于代理模式 ,代理类型包括:静态代理、动态代理。
静态代理
AspectJ(编译时增强)使用的是静态代理。所谓静态代理指的是,AOP框架会在编译阶段生成AOP代理类,它会在编译阶段将AspectJ植入到Java字节码中,运行的时候就是增强后的AOP对象。

AspectJ实现方式上依赖于特殊的AJC编译器,它并非是SpringAOP框架的一部分,而是SpringAOP使用了AspectJ的Annotation(注解),用来定义切面、切点等功能。
动态代理
SpringAOP使用的是动态代理。所谓动态代理指的是,AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法。
JDK动态代理
JDK动态代理要求被代理类必须实现一个接口,核心是InvocationHandler接口和Proxy类。JDK动态代理调用了Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h),通过该方法生成字节码,动态的创建一个代理类。interfaces参数是该动态类所继承的所有接口,而继承InvocationHandler接口的类则是实现在调用代理接口方法前后的具体逻辑。当

我们调用代理类对象的方法时,都会委托到InvocationHandler.invoke(Object proxy, Method method, Object[] args)方法,代理类对象作为proxy参数传入,参数method标识了我们具体调用的是代理类的哪个方法,args为这个方法的参数。
2.2.2 CGLIB动态代理

CGLIB(Code Generation Library)底层使用了ASM(一个短小精悍的字节码操作框架)来操作字节码生成新的类,除了CGLIB库外,脚本语言(如Groovy何BeanShell)也使用ASM生成字节码。

CGLIB既能代理接口也能代理类,如果某个类被标记为final,是无法使用CGLIB做动态代理。
何时使用JDK动态代理还是CGLIB?
如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP。
如果目标对象实现了接口,可以强制使用CGLIB实现AOP。
如果目标对象没有实现了接口,必须采用CGLIB库,Spring会自动在JDK动态代理和CGLIB之间转换。

相关术语

切面(Aspect):切面是通知和切点的结合,通知和切点共同定义了切面的全部内容,一般使用@Aspect实现切面的定义;
通知(Advice):通知定义了切面是什么以及何时使用,如Before、After;
切点(PonitCut):切点定义了在何处应用连接点(JoinPonit),通常使用明确的类和方法名称,或是利用正则表达式定义所匹配的类和方法名称来指定这些切点;
连接点(JoinPonit):连接点是在应用执行过程中能够插入切面的一个点,这个点可以是调用方法时、抛出以异常时、甚至修改一个字段时;
目标对象(Target):需要被代理的类,如UserService;
织入(Weaving):织入是把切面应用到目标对象并创建新的代理对象的过程

织入方式

编译时织入:需要特殊的编译器,如AspectJ;
类加载时织入:需要特殊的类加载器,如ClassLoader;
运行时织入:Spring采用动态代理的方式实现运行时织入,如SpringAOP。

通知类型

前置通知(Before):在目标方法被调用之前调用通知功能;
后置通知(After):在目标方法执行完成之后调用通知,此时不会关心方法的输出是什么;
返回通知(After-returning):在目标方法成功执行之后调用通知;
异常通知(After-throwing):在目标方法抛出异常后调用通知;
环绕通知(Around):在被通知的方法调用之前和调用之后执行自定义的行为。

springbean的生命周期?

以ApplocationContext上下文单例模式装配bean为例,深入探讨bean的生命周期:
在这里插入图片描述
Springfactory装配bean
在这里插入图片描述

1、实例化一个Bean--也就是我们常说的new;
2、按照Spring上下文对实例化的Bean进行配置--也就是IOC注入;
3、如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值
4、如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(setBeanFactory(BeanFactory)传递的是Spring工厂自身(可以用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就可以);
5、如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(同样这个方式也可以实现步骤4的内容,但比4更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法);
6、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;
7、如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。
8、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法、;
注:以上工作完成以后就可以应用这个Bean了,那这个Bean是一个Singleton的,所以一般情况下我们调用同一个id的Bean会是在内容地址相同的实例,当然在Spring配置文件中也可以配置非Singleton,这里我们不做赘述。
9、当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;
10、最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

spring事务实现方式?原理?

实现方式:
Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。
原理:
①编程式事务管理使用TransactionTemplate。
②声明式事务管理建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。
声明式事务最大的优点就是不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明或通过@Transactional注解的方式,便可以将事务规则应用到业务逻辑中。

声明式事务管理要优于编程式事务管理,这正是spring倡导的非侵入式的开发方式,使业务代码不受污染,只要加上注解就可以获得完全的事务支持。唯一不足地方是,最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。

spring的事务传播行为:

spring事务的传播行为说的是,当多个事务同时存在的时候,spring如何处理这些事务的行为。

① propagation_required:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
必须prp割醒   ----- r快恩t
② propagation_supports:支持当前事务,如果当前存在事务,就加入
该事务,如果当前不存在事务,就以非事务执行。
支持、死破恩吃
③ propagation_mandatory:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。
强制的,买no都投r
④ propagation_requires_new:创建新事务,无论当前存不存在事务,都创建新事务。
需要 、r快额死
⑤ propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
被需要的、 死破扯儿的
⑥ propagation_never:以非事务方式执行,如果当前存在事务,则抛出异常。
从未、耐我奥 
⑦ propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按required属性执行。
嵌套、耐死得的

Spring中的隔离级别:

① isolation_default:这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。

② isolation_read_uncommitted:读未提交,允许另外一个事务可以看到这个事务未提交的数据。

③ isolation_read_committed:读已提交,保证一个事务修改的数据提交后才能被另一事务读取,而且能看到该事务对已有记录的更新。

④ isolation_repeatable_read:可重复读,保证一个事务修改的数据提交后才能被另一事务读取,但是不能看到该事务对已有记录的更新。

⑤ isolation_serializable:一个事务在执行的过程中完全看不到其他事务对数据库所做的更新。

Spring框架中有哪些不同类型的事件?

Spring 提供了以下5种标准的事件:
(1)上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。

(2)上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。

(3)上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。

(4)上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。

(5)请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。

如果一个bean实现了ApplicationListener接口,当一个ApplicationEvent 被发布以后,bean会自动被通知。

springmvc的原理,如何请求匹配到相应的方法,以及如何匹配到相应的页面并渲染?

完整请求相应流程:
(1)用户发送请求至前端控制器DispatcherServlet;
(2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
(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响应用户。

如何找到页面的?

controller层的方法的返回值类型有3种:

1 ModelAndView 
ModelAndView对象 既可以存放数据也可以存放视图
2 void      不返回视图,只返回json数据    通常在与Ajax交互时使用
3 String          通过model存放数据   推荐使用

如果一个定时任务出现异常怎样处理?

首先得看是程序本身的问题还是线程问题?
本身问题:得需要修补代码,以及捕获响应的异常
线程问题:看是请求端的阻塞还是网络原因

一个定时任务如果出现并发情况,如何处理?

spring定时任务默认是单线程的。
<!-- 定时器配置 -->
<task:annotation-driven/>
<task:scheduler id="myScheduler" pool-size="5"/>

除了加线程池配置之外,定时任务线程还是会相互影响的话,需要 @Async异步执行
单线程执行,则不需要加定时线程池

如何利用spring的框架特性,开发自定义注解?

@Target:指定注解支持的使用范围,取值范围 ElementType
@Retention: 指定注解的保留时间,取值范围 RetentionPolicy
@Documented: 指定拥有这个注解的元素是否可以被Javadoc工具文档化
@Inherited: 指定该注解是否可以被继承

定义一个接口:将需要的注解加入里,然后只需要一个注解实现全部功能
复合注解:
@Service
@Transactional(rollbackFor = Exception.class,timeout=5)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface TransactionalService {
}

Mybatis如何进行分页?

第一种:Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。
第二种:可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。

Sql注入原理?

sql注入就是通过表单提交或者url等方式,在你系统可执行的sql语句中,插入符合sql语法要求的字符串,导致原始sql语句逻辑别打乱,执行了攻击者的恶意代码,从而达到获取你数据库敏感信息或攻击数据库的目的。
注入的类型?

数字型注入点
select * from 表名 where id=1 and 1=1
字符型注入点

select * from 表名 where name='admin' and 1=1 '
搜索型注入点
select * from 表名 where 字段 like '%测试%' and '%1%'='%1%'
还有很多注入点.......

如何预防?

1、输入数据长度的限制
2、过滤器器,进行关键字过滤:
3、预编译处理防止注入

主键生成策略?

1、hibernate:
<generator class="assigned"></generator>
2、Identity(MYSQL自增)
<generator class="identity"></generator>
3、Increment(会造成主键重复)
<generator class="increment"></generator>
4、Sequence(Oracle)
<generator class="sequence"></generator>

mybatis批量插入用什么?

在这里插入图片描述
在这里插入图片描述

怎样发布一个http接口供外部调用?

和咱们写普通方法没什么区别,你只要设定好返回的数据格式就行,比如:xml或者是json格式!
例子:json

Xml

Spring不同场景下的事务回滚?

情况1:如果没有在程序中手动捕获异常
@Transactional(rollbackOn = { Exception.class })  public void test() throws Exception {  
     doDbStuff1();  
     doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作   会回滚。  
}  

情况2:如果在程序中自己捕获了异常
@Transactional(rollbackOn = { Exception.class })  public void test() {  
     try {  
        doDbStuff1();  
        doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作  不会回滚。  
     } catch (Exception e) {  
           e.printStackTrace();     
     }  
}  

情况3:现在如果我们需要手动捕获异常,并且也希望抛异常的时候能回滚肿么办呢?
  下面这样写就好了,手动回滚事务:

@Transactional(rollbackOn = { Exception.class })  public void test() {  
     try {  
        doDbStuff1();  
        doDbStuff2();  
     } catch (Exception e) {  
          e.printStackTrace();     
          TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//就是这一句了,加上之后,如果doDbStuff2()抛了异常,                                                                                       //doDbStuff1()是会回滚的       }  
}  
发布了78 篇原创文章 · 获赞 6 · 访问量 6711

猜你喜欢

转载自blog.csdn.net/YHM_MM/article/details/105331801