SpringMVC
1.用户发送请求至 前端控制器DispatcherServlet。
2.前端控制器DispatcherServlet收到请求后调用处理器映射器HandlerMapping。
3.处理器映射器HandlerMapping根据请求的Url找到具体的处理器,生成处理器对象Handler及处理器拦截器HandlerIntercepter(如果有则生成)一并返回给前端控制器DispatcherServlet。
4.前端控制器DispatcherServlet通过处理器适配器HandlerAdapter调用处理器Controller。
5.执行处理器(Controller,也叫后端控制器)
6.处理器Controller执行完后返回ModelAnView。
7.处理器映射器HandlerAdapter将处理器Controller执行返回的结果ModelAndView返回给前端控制器DispatcherServlet。
8.前端控制器DispatcherServlet将ModelAnView传给视图解析器ViewResolver。
9.视图解析器ViewResolver解析后返回具体的视图View。
10.前端控制器DispatcherServlet对视图View进行渲染视图(即:将模型数据填充至视图中)
11.前端控制器DispatcherServlet响应用户。
SpringMVC的注解
@Controller(“name”)一般不会将其controller注入,所以可以不写name
@RequestMapping(value="/text", method = RequestMethod.GET) url以及请求方式 / 子配置路径在类上加表示所有传入该controller的请求前缀
@ResponsBody将数据封装成JSON写
@ModelAttribute:将key-value组装为Model
@RequsetBody 参数要求严格
参数绑定
在Spring.xml中排除扫描controller的方法.<context:exclude-filter type=”annotation” expression=”XX.XX.XX.controller ”>
避免父子容器同时注解生成两套bean,导致冲突.
web.xml
避免写很多<listener>,通过Spring监听类代替
<servlet>用Spring-MVC代替
@ControllerAdvice & @ExceptionHandler AOP方式 可以捕捉整个项目的异常
controller抛出的一场会被@ControllerAdvice捕获,并交给@ExceptionHandle处理,并通过@ResponseBody返回JSON
Spring将checkExpectionExpection转化成runtimeException从而让本该需要写代码捕获处理的异常转换
测试
@Test
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-tx.xml"})
将相应的xml文件导入
Spring
AOP的作用
在OOP中,正是这种分散在各处且与对象核心功能无关的代码(横切代码)的存在,使得模块复用难度增加。AOP则将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),切面将那些与业务无关,却被业务模块共同调用的逻辑提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。
特性:
(1)通知(增强)Advice
通知定义了切面是什么以及何时使用,应该应用在某个方法被调用之前?之后?还是抛出异常时?等等。
(2)连接点 Join point
连接点是在应用执行过程中能够插入切面的一个点。这个点可以是调用方法时,抛出异常时,甚至修改一个字段时。切面代码可以利用这些点插入到应用的正常流程中,并添加新的行为。
(3)切点 Pointcut
切点有助于缩小切面所通知的连接点的范围。如果说通知定义了切面的“什么”和“何时”的话,那么切点就定义了“何处”,切点会匹配通知所要织入的一个或多个连接点,一般常用正则表达式定义所匹配的类和方法名称来指定这些切点。
(4)切面 Aspect
切面是通知和切点的结合。通知和切点定义了切面的全部内容——它是什么,在何时何处完成其功能。
(5)引入 Introduction
引入允许我们向现有的类添加新方法或属性,从而无需修改这些现有类的情况下,让他们具有新的行为和状态。
(6)织入 Weaving
在过去我常常把织入与引入的概念混淆,我是这样来辨别的,“引入”我把它看做是一个定义,也就是一个名词,而“织入”我把它看做是一个动作,一个动词,也就是切面在指定的连接点被织入到目标对象中。
DI 和 IOC 概念
依赖注入或控制反转的定义中,调用者不负责被调用者的实例创建工作,该工作由Spring框架中的容器来负责,它通过开发者的配置来判断实例类型,创建后再注入调用者。由于Spring容器负责被调用者实例,实例创建后又负责将该实例注入调用者,因此称为依赖注入。而被调用者的实例创建工作不再由调用者来创建而是由Spring来创建,控制权由应用代码转移到了外部容器,控制权发生了反转,因此称为控制反转。
ApplicationContext
ApplicationContext是BeanFactory的子接口,也被称为应用上下文。BeanFactory提供了Spring的配置框架和基本功能,ApplicationContext则添加了更多企业级功能(如国际化的支持),他另一重要优势在于当ApplicationContext容器初始化完成后,容器中所有的 singleton Bean 也都被实例化了,也就是说当你需要使用singleton Bean 是,在应用中无需等待就可以用,而其他BeanFactory接口的实现类,则会延迟到调用 getBean()方法时构造,ApplicationContext的初始化时间会稍长些,调用getBean()是由于Bean已经构造完毕,速度会更快。因此大部分系统都使用ApplicationContext,而只在资源较少的情况下,才考虑使用BeanFactory。
BeanFactory
Spring使用BeanFactory来实例化、配置和管理对象,但是它只是一个接口,里面有一个getBean()方法。我们一般都不直接用BeanFactory,而是用它的实现类ApplicationContext,这个类会自动解析我们配置的applicationContext.xml,然后根据我们配置的bean来new对象,将new好的对象放进一个Map(处理器映射器HandlerMapping)中,键就是我们bean的id,值就是new的对象。
Spring注入有两种实现方式
1)利用xml配置文件
<context:property-placeholder location="***.properties"> 定义需要加载的配置文件
<import resource="×××.xml"/> 引入其他xml文件
<bean id ="***" class=""> 定义bean,class是对应的类。property用于set注入,constructor-arg构造器注入,ref表示其他bean
<context:component-scan base-package="***"/> 指定spring要扫描的类,需要扫描多个,直接用","分隔
2)采用注解的方式
<context:annotation-config /> 根据注解对spring bean进行装配
@Repository,@Service,@Component,@Controller 这四个都是定义一个bean,但是对应web服务的不同层。bean最好是定义名字,全局唯一的ID,防止bean找不到
@Resource(name="***") 注入bean
@Value 实现传参
注解和xml方式效果差不多;注解方式写起来会方便一些;xml可以很方便地进行修改,例如,需要修改某个bean的class,就可以直接修改xml文件;引入外部jar包里面的bean就只能使用xml。
SpringBoot
@RestController 标识控制层并Return 返回json
@ResponseBody(返回JSON)+@Controller(控制层处理HTTP请求)
@ResponseBody 对Controller的方法返回值进行序列化
该方法的返回结果直接写入HTTP response body中
一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@responsebody后返回结果不会被解析为跳转路径,而是直接写入HTTP response body中。比如异步获取json数据,加上@responsebody后,会直接返回json数据。
@RequestMapping Url映射 有如下简写形式 @Mapping(“value”)
@GetMapping @DeleteMapping @PutMapping @PostMapping
@PathVariable 获取Url中'/x '的x的值(Mapping中用/{x}标识)
@RequestParam 获取Url中'/?x= '的x的值(Mapping中不需要标识)
@Aspect 表示AOP
@Component表示一个组件 (Bean) ,可以作用在任何层次
// 服务层的切入点
@Pointcut("execution(public * com.calm.girl.control.GirlController.girlList(..))")
public void log() {}
@Service 标识业务层
@Transactional 声明事务
@Autowired 声明注入
@Entity 标识实体类
@Id // 主键