1、核心思想·
- IDC-控制反转
- Dl依赖注入
1.1 IOC理解
spring通过一种称作控制反转(IOC)的技术促进了,当引用IOC,一个对象依赖的其他对象会通过被动封方式传递进来,而不是这个对象自己创建或者查找依赖对象,你可以认为IOC与JND相反——而不是对象从容器中查找依赖,而是容器在对象初始化时不等请求就主动将依赖传递给它。
1.2DI(依赖注入)理解
依赖注入,是指程序员运行过程中,如果需要调用另一个对象帮忙时,无须在代码中创建被调用者,
而是依赖于Spring容器的注入。Spring的依赖注入对调用者和被调用者几乎没有任何要求,完全
支持对POJO之间依赖关系的管理。
2.Bean的生命周期
2.4 Bean的作用域
scope: bean的作用域
1.singleton 单例(spring默认使用),在spring的整个生命周期当中只会创建一次 ,创建对象的时机是在spring上下文被创建的时候。
2.prototype 原生(也叫多例),getBean时每一次都会创建新的实例使用,对象是在getBean的时候被创建,这点与singleton有区别
3.request 在同一个request中有效,比较少用
4.session 在同一个session会话中有效,比较少用
bean.xml配置
2.5常用注解
@Autowired 根据类型依赖注入,可以写在字段,方法。构造方法,方法的参数前面
@Qualifier 结合 @Autowired 一起使用用于根据名称进依赖注入
为什么要用Qualifier?因为spring容器当中可能存在多个相同类型的实例对象
根据字段类型已经无法 区分注入对象,这时需要根据bean的 唯一名称进行区分。
@Resource 功能==@Autowired + @Qualifier
@Resource 与 @Autowired区别:
@Autowired 是属于spring框架当中的注解
@Resource 是属于jdk的注解,一般写在类上
一般默认使用类名作为bean的id名称,注意:类名的第一个字母是小写
@Bean 在方法中手动装配对象是使用
@Configuration 加在类上的作用是声明一个配置类,功能相当于bean.xml
@PropertySource 可以导入properties属性到spring当中
@value 可以注入属性值到对象的字段当中
项目开发当中常用的注解:
项目开发当中,代码经常被设计分层结构,一般分为以下三层,控制层(Controlier)------(service)+dao层(持久层)所以spring当中提供了对应的三层代码注解
- @Controller
- 使用在web层类上用于实例化Bean
- @Service
- 使用在业务层(Service层)类上用于实例化Bean
- @Repository
- 持久层注解,主要使用在数据库等数据持久层代码当中的类上,用于实例化Bean
以上三个注解不仅可以写在类上,勇士也可以写在接口上,写在接口上,那么实现了该接口
的类都将被spring实例化成bean
2.6 Bean生命周期
Spring的bean设计,为了给开发人员提供足够的拓展点,在容器内部设计了一套bean创建流程机制,在这套机制里每个时间节点都有对应的活干,这些拓展点如何使用,以及执行的步骤,示例代码如下:
public class Simple implements InitializingBean, SmartInitializingSingleton { //Bean的生命周期演示 public Simple(){ System.out.println("Simple()构造方法"); } @PostConstruct //在对象加载完依赖注入后执行 public void PostConstruct(){ System.out.println("PostConstruct 方法执行... 构造方法之后"); } //bean的属性值被注入之后执行的方法 @Override public void afterPropertiesSet() throws Exception { System.out.println("属性设置方法"); } public void init(){ System.out.println("init 方法执行... 创建阶段"); } //只有当前bean是 (singleton)--单线程 才会执行 //在spring中,所有的bean完成 初始化,并且所有字段属性已经注入完毕之后 @Override public void afterSingletonsInstantiated() { System.out.println("afterSingletonsInstantiated 正在执行"); } @PreDestroy public void PreDestroy(){ System.out.println("PreDestroy 方法执行... 销毁方法之前"); } public void destroy(){ System.out.println("destroy 方法执行... 销毁阶段"); } }
3 Spring-mvc学习
3.1简介
它是spring组织设计的一个提供快速构建Web应用程序的全功能MVC(model-web-controller)模块,到目前为止已经基本取缔了早期类似的Web框架Struts。Spring-MVC支持多种视图技术,比如:Freemarker,Beetl,jsp,Themyleaf等等。
3.1.2spring-mvc运行原理
3.1.3运行时序图
3.1.4拦截机制流程图
3.2功能注解总结
@RestController 定义控制器全部都返回json
@Controller 定义普通控制器
@RestController 与 @Controller区别,@RestController = @Controller+@Responsebody
@RequestMapping 定义url
@ResponseBody 响应json数据
@RequestBody 接收json对象
@GetMapping 是@RequestMapping(method = {RequestMethod.GET})的简写
@PostMapping 是@RequestMapping(method = {RequestMethod.POST})的简写
@PathVariable 功能讲解,与@RequestMapping搭配使用的讲解
@MatrixVariable 组合条件路径传参
@RequestParam 接收参数
@ControllerAdvice 是控制器的增强处理,主要处理异常
@ExceptionHandler 定义要捕捉的异常类
@ResponseStatus 响应的状态
@ControllerAdvice + @ExceptionHandler +@ResponseStatus+@ResponseBody 组合使用讲解
搭建springmvc的web工程教程说明
4.工程搭建
4.1引入依赖
<!--Spring坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency> <!--SpringMVC坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.0.5.RELEASE</version> </dependency> <!--Servlet坐标--> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <!--Jsp坐标--> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> </dependency> <!--Jackson包 json转对象,对象转json工具包--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency>
4.2Spring框架配置
创建XML配置文件,spring-web-mvc.xml,配置springmvc框架
4.2.1Spring-web-mvc.XML框架配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 定义spring的扫描--> <context:component-scan base-package="com.zz.springmvc.controller"/> <!-- 配置视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 设置视图存放路径--> <property name="prefix" value="/WEB-INF/jsp/"/> <!-- 设置视图文件后缀名--> <property name="suffix" value=".jsp"/> </bean>
4.2.2 Web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <!-- 要加载的spring-mvc.xml 配置文件--> <param-value>classpath:spring-web-mvc.xml</param-value> </init-param> <!-- 在web项目启动时完成 初始化--> <load-on-startup>1</load-on-startup> </servlet> <!-- 映射当中为/ 代表处理任何请求--> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--注册声明过滤器--> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <!--指定项目的编码格式--> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <!--强制请求对象的编码格式 使用字符集encoding--> <init-param> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <!--强制响应对象使用encoding的字符集编码--> <init-param> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
4.2.3 Spring-web-mvc.XML-json配置
<!-- 注解的适配器和映射器 --> <mvc:annotation-driven> <mvc:message-converters> <!--@ResponseBody 中文响应乱码 --> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value> text/plain;charset=UTF-8 </value> <value> text/html;charset=UTF-8 </value> <value> application/json;charset=UTF-8 </value> <value> application/x-www-form-urlencoded;charset=UTF-8 </value> </list> </property> </bean> <!-- JSON中文请求乱码及解决 HttpMediaTypeNotAcceptableException: Could not find acceptable representation 异常信息--> <bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value> application/json;charset=UTF-8 </value> <value> application/x-www-form-urlencoded;charset=UTF-8 </value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
4 拦截器
4.1定义拦截器
//@Order 多个拦截器时控制拦截器执行的先后顺序,值越小越靠前 可以为负数 @Order(1) public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); /** * 返回true 校验通过 * 返回false 校验不通过 */ return true; } /** * 功能类似于过滤器 * 进入到控制器方法前执行 * 使用场景:登录状态校验,解析令牌,黑名单ip拦截 */ @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle"); } /** * * 完成方法 * 视图渲染后执行 * 最后执行 */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion"); } }
4.4.2 Spring-web-mvc.XML--拦截器配置
拦截器定义好后,需要配置springmvc框架中。需要spring-web-mvc.xm中加入以下配置
配置拦截器--> <mvc:interceptors> <mvc:interceptor> <!-- 设置拦截器路径,拦截地址以/interceptor开关的所有请求--> <mvc:mapping path="/interceptor/*"/> <!-- 配置拦截器bean--> <bean class="com.zz.springmvc.controller.interceptor.MyInterceptor"></bean> </mvc:interceptor> <mvc:interceptor> <!-- 设置拦截器路径,拦截地址以/interceptor开关的所有请求--> <mvc:mapping path="/interceptor/*"/> <!-- 配置拦截器bean--> <bean class="com.zz.springmvc.controller.interceptor.MyInterceptor1"></bean> </mvc:interceptor> </mvc:interceptors>
5.异常和谐处理
页面访问过程中,可能会产生异常,异常信息当中可能包含一些敏感的系统核心信息,比如数据库用户名,秘钥等信息!非常容易影响到系统安全,而且用户体验也不好,所有一般而需要和谐掉功能异常产生的异常信息,异常增强处理的方式代码如下
/** * 全局异常和谐处理增强器 */ @ControllerAdvice // @RestControllerAdvice=@ControllerAdvice+@RequestBody public class GlobalExceptionHandler { /** * NullPointerException 要设置和谐的异常类型 */ @ResponseStatus(HttpStatus.BAD_REQUEST) @ExceptionHandler({NullPointerException.class}) public String puzzExceptionHandler(NullPointerException ex){ System.out.println("puzzExceptionHandler"); //打印异常的堆栈信息 ex.printStackTrace(); return "ex"; } /** *兜底异常处理 * 先精确匹配异常处,匹配不到就走兜底异常处理 */ @ExceptionHandler({Exception.class}) public String ExceptionHandler(Exception ex){ System.out.println("ExceptionHandler"); //打印异常的堆栈信息 ex.printStackTrace(); return "ex"; } }
5.1异常和谐处理配置
web.xml的配置
<!-- 配置错误页面--> <error-page> <!-- 配置404状态码错误指定信息--> <error-code>404</error-code> <location>/404</location> </error-page>
Spring-web-mvc.xml
<!-- 当访问系统的静态页面的时候不需要servlet处理--> <mvc:resources mapping="/html/*" location="/html/"> </mvc:resources>
404页面 ,纯html页面
<html> <head> <title>无法访问</title> </head> <body> <h2>没有找到你想要访问的页面!<a href="/Json3">点击跳回首页</a> </h2> </body> </html>
6.文件上传
@RestController public class FileUploadController { /** *单文件上传 */ //name带表文本框内容,myFile代表文件内容 上传数据要与名字相同 @PostMapping("/Upload") public String upload(String name, MultipartFile myFile){ System.out.println(String.format("name=%s",name)); //获取上传文件的原名 String originalFilename = myFile.getOriginalFilename(); System.out.println(String.format("源文件名=%s",originalFilename)); try { //写入文件到磁盘当中2 myFile.transferTo(new File("C:\\upload\\"+originalFilename)); } catch (IOException e) { e.printStackTrace(); } return "success"; } /** *多文件上传 */ @PostMapping("/Uploads") public String uploads(String name, MultipartFile [] uploadFiles){ System.out.println(String.format("name=%s",name)); //获取上传文件的原名 Arrays.stream(uploadFiles).forEach((uploadFile)->{ if(!uploadFile.isEmpty()){ /** * 上传文件的源文件名 */ String originalFilename = uploadFile.getOriginalFilename(); System.out.println(String.format("文件名=%s",originalFilename)); try { //将上传文件数据写入到磁盘当中 uploadFile.transferTo(new File("C:\\upload\\"+originalFilename)); } catch (IOException e) { e.printStackTrace(); } } }); return "success"; } }
6.1文件上传的配置
配置在Spring-web-mvc.xml
<!-- 文件上传解析器--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 设置数据默认编码格式--> <property name="defaultEncoding" value="UTF-8"/> <!-- 设置单个文件最大允许上传的大小10mb 单位字节--> <property name="maxInMemorySize" value="10485760"/> </bean>