面向切面编程 (AOP)
面向切面编程是一种编程范式,用于在程序中分离关注点,例如日志记录、事务管理和安全性。它主要由以下几个关键组成部分构成:
连接点 (Join Point):在程序执行过程中可以插入切面的点,通常是方法的执行点。
切点 (Pointcut):确定在何处应用切面的一组连接点的定义。
通知 (Advice):在切点处执行的动作,包括前置、后置、异常、返回和环绕通知。
切面 (Aspect):切点和通知的组合。
package com.easy.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class AOPObj {
//定义切点
@Pointcut("execution(* com.easy.controller.EasyAController.testA(..))")
public void pointCuttesta(){}
@Before("pointCuttesta()")
public void before(){
System.out.println("----------前置通知");
}
}
代理模式
代理模式是一种结构型设计模式,通过代理对象控制对原始对象的访问。主要有两种类型:
静态代理:代理类在编译时已知道要代理的对象。
动态代理:代理类在运行时动态创建,可以代理任意实现了特定接口的对象。
动态代理的实现方式:
JDK动态代理:基于接口的代理,被代理的对象必须实现接口,利用 java.lang.reflect.Proxy 和 java.lang.reflect.InvocationHandler 实现。
CGlib动态代理:通过继承被代理类来实现代理,可以代理没有实现接口的类,但不能代理 final 类。
package com.easy.proxy.dynamic.jdk;
import com.easy.proxy.staticproxy.EasyA;
import com.easy.proxy.staticproxy.Proxy;
public class Factory {
public static Object getProxy(Object obj){
//JDK代理只能实现接口中的方法
return Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
//类加载器
obj.getClass().getInterfaces(),
//实现接口
new EasyInvocationHandler(obj)
);
}
public static void main(String[] args) {
EasyObj easy=new EasyObj();
Object obj=getProxy(easy);//动态生成的一个代理类的对象
if(obj instanceof EasyInterface){
System.out.println("obj是代理对象是EasyInterface的实例");
EasyInterface e=(EasyInterface)obj;
e.easy();
}
Class c=obj.getClass();
System.out.println(c);
EasyA easya=new EasyA();
obj=getProxy(easya);
System.out.println(obj.getClass());
}
}
Spring MVC
Spring MVC 是基于 Spring 框架的一种 Web 框架,用于开发 Web 应用程序。它主要由以下几个关键部分组成:
@Controller 和 @RestController:用于定义控制器类,处理 HTTP 请求。
@RequestMapping:用于将 HTTP 请求映射到控制器的处理方法上。
@PathVariable:用于从 URL 中获取参数。
@RequestParam:用于从 HTTP 请求中获取参数。
@GetMapping / @PostMapping / @PutMapping / @DeleteMapping:简化的 HTTP 方法映射注解。
package com.easy.controller;
import com.easy.bean.Staff;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
//REST 请求资源状态转换
// get post put delete
//get user/1 获取 user/get
//post user.... 新增 user/add
//delete user/1 删除 user/delete?id=1
//put user.... 编辑 user/edit
@RestController
//@Controller
@RequestMapping("user")
public class EasyDController {
@RequestMapping("easyaa")
public String easyaa(){
return "easyaa method";
}
@RequestMapping("parama")
public String paramA(String name){
return "springmvc接收到的参数是:"+name;
}
//同时接收多个参数 MAP 接收 非常灵活
@RequestMapping("paramb")
public Map paramb(@RequestParam Map params){
return params;
}
//使用封装对象接收参数 程序中只接受我们需要的数据
@RequestMapping("paramc")
public Staff paramc(Staff staff){
return staff;
}
//获取地址上的参数
@RequestMapping("paramd/{id}")
public String paramd(@PathVariable Integer id, HttpServletRequest request){
String username=request.getParameter(("username"));
return "接收到的参数是:"+id;
}
//作用域对象:page HttpServletrequest Httpsession (ServletContext)application
//接受前端的参数
public static void getparam(){
}
}
package com.easy.controller;
import com.easy.bean.Staff;
import com.easy.common.CommonResult;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
@RestController
//@RequestMapping("staff")
public class StaffController {
@GetMapping("staff")
public CommonResult getList(Staff staff){
List<Staff> list=null;
System.out.println("获取数据");
return CommonResult.success(list);
}
@PostMapping("staff")
public CommonResult addstaff(Staff staff){
System.out.println("新增数据");
return CommonResult.success();
}
@DeleteMapping("staff/{id}")
public CommonResult delstaff(@PathVariable int id){
System.out.println("删除数据"+id);
return CommonResult.success();
}
@PutMapping("staff")
public CommonResult editstaff(Staff staff){
System.out.println("编辑数据");
return CommonResult.success();
}
@GetMapping("ex")
public CommonResult ex(){
int a=12/0;
return CommonResult.success();
}
@ExceptionHandler(Exception.class)
@ResponseBody
public CommonResult exh(){
return CommonResult.success(200,"稍有问题");
}
}
转发和重定向
转发forward:同一个服务器中不同的服务进行转发。
浏览器发送了一个请求 可以转发到项目中受保护的资源,比如web-inf。转发是request对象执行forward方法。
重定向redirect:可以在不同的服务之间跳转。
浏览器发送两次请求,重定向是通过response对象通知浏览器重新访问(redirect)。
package com.easy.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class EasyEController {
//转发forward:同一个服务器中不同的服务进行转发
//浏览器发送了一个请求 可以转发到项目中受保护的资源
//比如web-inf
//转发是request对象执行forward方法
//重定向redirect:可以在不同的服务之间跳转
//浏览器发送两次请求
//重定向是通过response对象通知浏览器重新访问(redirect)
@RequestMapping("methodA")
public String methodA(){
System.out.println("---------methodA");
//return "forward:/methodB";
return "redirect:/methodB";
}
@RequestMapping("methodB")
@ResponseBody
public String methodB(){
System.out.println("----------methodB");
return "this is methodB";
}
@RequestMapping("methodC")
public String methodC(){
System.out.println("--------methodC");
return "index.jsp";
}
}
运行原理及关键技术点:
拦截器:通过实现 HandlerInterceptor 接口来拦截请求和处理。
异常处理机制:通过 @ExceptionHandler 和 @ControllerAdvice 实现全局异常处理和局部异常处理。
拦截器(Interceptor)
拦截器是 Spring MVC 提供的一种机制,用于在请求处理的不同阶段执行预处理和后处理操作。实现了 HandlerInterceptor 接口,该接口定义了三个主要方法:
preHandle:
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
功能:在请求处理之前被调用,可以进行请求拦截、权限校验等操作。
返回值:
true:继续执行后续的拦截器和处理器(Controller)。
false:阻止后续的拦截器和处理器执行,请求处理流程中断。
postHandle:
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;
功能:在请求处理之后,视图渲染之前调用。可以通过 ModelAndView 对象对请求进行进一步处理或修改。
afterCompletion:
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;
功能:在整个请求处理完成后调用,即视图渲染完毕后。通常用于进行资源清理操作,例如释放资源、记录日志等。
异常处理
异常处理是在控制器处理请求过程中可能抛出异常时的处理机制。Spring MVC 提供了几种处理异常的方式:
局部异常处理:在控制器类中使用 @ExceptionHandler 注解处理特定异常类的异常。
全局异常处理:通过在整个应用范围内定义 @ControllerAdvice 类来处理全局异常。
通常在全局异常处理中,可以定义多个 @ExceptionHandler 方法来处理不同类型的异常,或者对未处理的异常进行统一处理和记录。
package com.easy.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class EasyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("---------preHandle");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("---------preHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("------------afterCompletion---整个请求处理完毕");
}
}
springmvc 运行原理
DispatcherServlet :
入口点:所有的请求都经过 DispatcherServlet,它是 Spring MVC 的核心控制器。
责任:负责请求的转发和处理,它将请求分发给合适的处理器(Handler)进行处理,并将处理结果返回给客户端。
HandlerMapping 的作用:
定位处理器:DispatcherServlet 通过 HandlerMapping 来确定请求所对应的处理器(Controller)。
HandlerMapping 实现:Spring MVC 提供多种 HandlerMapping 的实现,包括基于 URL 的映射、注解映射等,以匹配请求到具体的处理器。
Controller 的角色:
请求处理:Controller 是实际处理请求的地方,它们使用 @Controller 或 @RestController 注解进行标识。
处理方法:Controller 中的方法通过 @RequestMapping 或其他注解映射特定的请求路径和请求方法,处理请求并返回响应数据。
HandlerAdapter 的作用:
适配处理器:HandlerAdapter 将请求交给 Handler(Controller) 进行处理,并负责调用合适的方法。
多样性支持:Spring MVC 提供了不同的 HandlerAdapter 实现,用于支持不同类型的处理器方法。
ViewResolver 和视图解析:
视图解析:处理完请求后,DispatcherServlet 通过 ViewResolver 将逻辑视图名解析为实际的视图。
返回结果:视图负责渲染最终的输出,然后返回给客户端。
拦截器和异常处理:
拦截器:通过 HandlerInterceptor 可以在请求处理的不同阶段执行预处理和后处理操作。
异常处理:通过 @ExceptionHandler 或全局异常处理器 @ControllerAdvice 可以统一处理控制器中抛出的异常