ssm
Spring
Spring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象。也可以称之为项目中的粘合剂。
Spring的核心思想是IoC(控制反转),即不再需要程序员去显式地new一个对象,而是让Spring框架帮你来完成这一切。
SpringMVC
SpringMVC在项目中拦截用户请求,它的核心Servlet即DispatcherServlet承担中介或是前台这样的职责,将用户请求通过HandlerMapping去匹配Controller,Controller就是具体对应请求所执行的操作。SpringMVC相当于SSH框架中struts。
mybatis
mybatis是对jdbc的封装,它让数据库底层操作变的透明。mybatis的操作都是围绕一个sqlSessionFactory实例展开的。mybatis通过配置文件关联到各实体类的Mapper文件,Mapper文件中配置了每个类对数据库所需进行的sql语句映射。在每次与数据库交互时,通过sqlSessionFactory拿到一个sqlSession,再执行sql命令。页面发送请求给控制器,控制器调用业务层处理逻辑,逻辑层向持久层发送请求,持久层与数据库交互,后将结果返回给业务层,业务层将处理逻辑发送给控制器,控制器再调用视图展现数据。
ioc
IOC:控制反转,是一个理论,概念,思想。
描述的:把对象的创建,赋值,管理工作都交给代码之外的容器实现,也就是对象的创建是有其它外部资源完成。
控制:创建对象,对象的属性赋值,对象之间的关系管理。
反转:把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现。由容器代替开发人员管理对象。创建对象,给属性赋值。
正转:由开发人员在代码中,使用new 构造方法创建对象,开发人员主动管理对象。
容器:是一个服务器软件,一个框架(spring)
aop
AOP 的主要作用就是在不侵入原有程序的基础上实现对原有功能的增强, 而增强的方式就是添加通知,就是额外增强一个方法。按照不同的方式通知又分为前置、后置、环绕、异常、带有返回值。
aop通知方式
| 注解 | 通知 |
|---|---|
| @Before | 通知方法会在目标方法调用之前执行 |
| @After | 通知方法会在目标方法返回或者异常后调用 |
| @AfterReturning | 通知方法会在目标方法返回后调用 |
| @AfterThrowing | 通知方法会在目标方法抛出异常后调用 |
| @Around | 通知方法会将目标方法封装起来 |
SpringBoot自动装配的方式
- 使用XML
- 使用注解
springboot是如何实现自动装配的?如何实现按需加载?
也是通过反射来实现的
springboot的核心注解@SpringBootApplication
@SpringBootApplication看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解的集合。
根据 SpringBoot 官网,这三个注解的作用分别是:
- @EnableAutoConfiguration:启用 SpringBoot 的自动配置机制。
- @Configuration:允许在上下文中注册额外的 bean 或导入其他配置类,作用与 applicationContext.xml 的功能相同。
- @ComponentScan: 扫描包下的类中添加了@Component (@Service,@Controller,@Repostory,@RestController)注解的类 ,并添加的到spring的容器中,可以自定义不扫描某些 bean。如下图所示,容器中将排除TypeExcludeFilter和AutoConfigurationExcludeFilter。
@EnableAutoConfiguration:实现自动装配的核心注解EnableAutoConfiguration只是一个简单地注解,自动装配核心功能的实现实际是通过AutoConfigurationImportSelector类。AutoConfigurationImportSelector:加载自动装配类AutoConfigurationImportSelector类实现了ImportSelector接口,也就实现了这个接口中的selectImports方法,该方法主要用于获取所有符合条件的类的全限定类名,这些类需要被加载到 IoC 容器中。
Spring框架中的单例Bean是线程安全的么?
不是安全的。
Spring中的Bean默认是单例模式的,框架并没有对bean进行多线程的封装处理。
注:单例bean是指IOC容器中就只有这么一个bean,是全局共享的,有多少个线程来访问用的都是这个bean。
如果Bean是有状态的,那就需要开发人员自己来进行线程安全的保证,最简单的办法就是改变bean的作
用域 把 "singleton"改为’‘protopyte’ 这样每次请求Bean就相当于是 new Bean() 这样就可以保证线程的
安全了。
- 有状态就是有数据存储功能。比如:一个Service里有个count的变量计数。
- 无状态就是不会保存数据
Spring支持的几种bean的作用域
- singleton:默认,每个容器中只有一个bean的实例,单例的模式由BeanFactory自身来维护。
- prototype:为每一个bean请求提供一个实例。
- request:为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。
- session:与request范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。
- global-session:全局作用域,global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。全局作用域与Servlet中的session作用域效果相同。
Spring MVC的执行流程
- 用户点击某个请求路径,发起一个HTTP request请求,该请求会被提交到Dispatcher Servlet(前端控制器);
- 由Dispatcher Servlet请求一个或多个Handler Mapping(处理器映射器),并返回一个执行链(Handler Execution Chain);
- Dispatcher Servlet将Handler Mapping返回的执行链中的Handler信息发送给Handler Adapter(处理器适配器);
- HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(常称为 Controller);
- Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC的底层对象,包括 Model 数据模型和 View 视图信息);
- HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet ;
- DispatcherServlet 接收到 ModelAndView 对象后,会请求 ViewResolver(视图解析器)对视图进行解析;
- ViewResolver 根据 View 信息匹配到相应的视图结果,并返回给 DispatcherServlet;
- DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,将 Model 中的模型数据填充到 View 视图中的 request 域,生成最终的 View(视图);
- 视图负责将结果显示到浏览器(客户端)
SpringMVC常用注解
- @RequestMapping:@RequestMapping注解的作用就是将请求 和 处理请求的 控制器方法 关联起来,建立映射关系。
SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的控制器方法来处理这个请求。
- @RequestParam:@RequestParam是将请求参数和控制器方法的形参创建映射关系
- @RequestHander:@RequestHeader是将请求头信息和控制器方法的形参创建映射关系
- @RequestBody:@RequestBody可以获取请求体,需要在控制器方法设置一个形参,使用@RequestBody进行标识,当前请求的请求体就会为当前注解所标识的形参赋值
- @ResponseBody:@ResponseBody用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器
- @RestController:@RestController注解是springMVC提供的一个复合注解,标识在控制器的类上,就相当于为类添加了@Controller注解,并且为其中的每个方法添加了@ResponseBody注解
- @ControllerAdvice:标记为异常处理类(Java代码异常,非Http请求状态异常),一个异常处理类有很多异常处理器。
- @ExceptionHandler:异常处理器,在异常处理类中声明
- @Configuration:声明此类为注解类,可代替xml配置
实体类中的属性名和表中的字段名不一样 怎么办?
- 第1种: 通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
- 第2种: 通过来映射字段名和实体类属性名的一一对应的关系
在mybatis中#和$的主要区别
\#传入的参数在SQL中显示为字符串,$传入的参数在SqL中直接显示为传入的值.
\#方式能够很大程度防止sql注入,$方式无法防止Sql注入;
传入的参数在SQL中显示不同
- \#传入的参数在SQL中显示为字符串(当成一个字符串),会对自动传入的数据加一个双引号。
- $传入的参数在SqL中直接显示为传入的值
- \#可以防止SQL注入的风险(语句的拼接);但$无法防止Sql注入。
- $方式一般用于传入数据库对象,例如传入表名。
- 大多数情况下还是经常使用#,一般能用\#的就别用$;但有些情况下必须使用$,例:MyBatis排序时使用order by 动态参数时需要注意,用$而不是\#。
mybatis中的一级缓存和二级缓存
一级缓存是 SqlSession 级别的缓存。在操作数据库时需要构造 SqlSession 对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的是 SqlSession 之间的缓存数据区(HashMap)是互相不影响。
二级缓存是 Mapper 级别的缓存,多个 SqlSession 去操作同一个 Mapper 的 sql 语句,多个 SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。