我们知道java文件在编译期间会成为class字节码文件, 运行时加载对应的类到方法区
所以使用JDK实现的原理就是
-
在运行期间, 根据被代理类, 生成代理类的字节码文件, 将被代理类包装到代理类中
-
被代理类方法执行前后, 统一处理逻辑
-
使用的时候:, 使用的是代理类 不再使用被代理类 因为我们的被代理类以及被代理类包裹了
CGLIB的实现方式
-
MethodInterceptor完成方法执行前后的业务逻辑插入, 再通过ASM字节码技术, 生成代理类的字节码,
-
当然这个也有前提条件: 被代理类不需要实现接口, 但不能为final修饰
-
使用@ControllerAdvice 和 @ExceptionHandler 实现 然后指定要捕获的异常类就可以了 (可以有多个)
-
自定义一个异常
package todayTest.application.modle;
/**
-
Created with IntelliJ IDEA.
-
Description: If you don’t work hard, you will a loser.
-
User: Listen-Y.
-
Date: 2020-08-18
-
Time: 10:13
*/
public class DiyException extends Exception {
public DiyException(String message) {
super(message);
}
}
- 配置web请求返回异常
//访问test12直接返回自定义异常
@RequestMapping(value = “test12”)
public Object test12() throws DiyException {
throw new DiyException(“这是一个自定义异常”);
}
- 实现@ControllerAdvice统一处理异常
package todayTest.application.interceptor;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import todayTest.application.modle.DiyException;
/**
-
Created with IntelliJ IDEA.
-
Description: If you don’t work hard, you will a loser.
-
User: Listen-Y.
-
Date: 2020-08-18
-
Time: 10:24
*/
//指名身份, 这是一个拦截Controller中web请求进行统一处理的类
@ControllerAdvice
public class AppControllerAdvice {
//指定处理请求方法中抛出的异常
@ExceptionHandler(DiyException.class)
@ResponseBody
public Object handler(DiyException d) {
return d.getMessage();
}
}
使用@ControllerAdvice注解实现 并且要实现ResponseBodyAdvice接口 (可以有多个)
- 创建自定义返回格式
package todayTest.application.modle;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
/**
-
Created with IntelliJ IDEA.
-
Description: If you don’t work hard, you will a loser.
-
User: Listen-Y.
-
Date: 2020-08-18
-
Time: 10:41
*/
//这是一个统一的返回数据格式
@Getter
@Setter
@ToString
public class ReturnFormat {
private boolean success; //请求是否成功
private Object data; //成功返回的数据
private String code; // 错误的话返回的提示信息
private String message; //描述
}
- 配置web请求
//web请求访问这里我们直接返回一个bean对象 然后使用统一数据格式对其进行封装
@RequestMapping(value = “test13”, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public Object test13() {
return test1;
}
- 实现ResponseBodyAdvice接口进行统一数据格式
package todayTest.application.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import todayTest.application.modle.DiyException;
import todayTest.application.modle.ReturnFormat;
/**
-
Created with IntelliJ IDEA.
-
Description: If you don’t work hard, you will a loser.
-
User: Listen-Y.
-
Date: 2020-08-18
-
Time: 10:24
*/
//指名身份, 这是一个拦截Controller中web请求进行统一处理的类
@ControllerAdvice
//实现ResponseBodyAdvice接口实现统一数据的封装
//注意要设置为Object类型
public class AppControllerAdvice implements ResponseBodyAdvice {
//指定处理请求方法中抛出的异常
@ExceptionHandler(DiyException.class)
@ResponseBody
public Object handler(DiyException d) {
return d.getMessage();
}
@Override
public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
//执行Controller中的web请求方法结束,返回数据到前端的时候,是否要重写响应体
//如果返回的是true就是要执行重写 反之不重写
//这里我们方便演示就让全部数据都要按照我们的自定义格式返回数据
return true;
}
@SneakyThrows
//大胆的抛出异常
@Override
public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
//如果存在返回字符串的情况,需要返回字符串类型,否则会报错
//解决方案:判断o对象的类型:
//如果是字符串,就返回objectmapper序列化后的字符串,否则返回统一封装的类型
if (o.getClass().equals(String.class)) {
//判断是字符串类型将数据以json格式返回
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(o);
}
//在这里我们统一返回我的自定义的ReturnFormat格式 将数据封装到这个格式里
// o就是我们返回的数据
ReturnFormat returnFormat = new ReturnFormat();
returnFormat.setSuccess(true);
returnFormat.setData(o);
returnFormat.setMessage(“返回的是我们自定义的格式”);
return returnFormat;
}
}
通过在@Configuration注解下实现WebMvcConfigurer接口, 重写接口方法来完成配置
-
如果要实现拦截器 就需要重写addInterpetor, 给定拦截的路径和排除拦截的路径, 最后匹配的结果 ,来决定是否执行拦截器中的方法
-
在@ConFiguration注解下实现WebMvcConfigurer接口 并重写addInterceptors方法指定拦截路径
package todayTest.application.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import todayTest.application.interceptor.LoginIInterceptor;
import todayTest.application.modle.Person;
import java.util.HashMap;
import java.util.Map;
/**
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://i-blog.csdnimg.cn/blog_migrate/64e6845182d738fd00da7324633e1f45.jpeg)
最后总结
搞定算法,面试字节再不怕,有需要文章中分享的这些二叉树、链表、字符串、栈和队列等等各大面试高频知识点及解析
最后再分享一份终极手撕架构的大礼包(学习笔记):分布式+微服务+开源框架+性能优化
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!**
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://i-blog.csdnimg.cn/blog_migrate/64e6845182d738fd00da7324633e1f45.jpeg)
最后总结
搞定算法,面试字节再不怕,有需要文章中分享的这些二叉树、链表、字符串、栈和队列等等各大面试高频知识点及解析
最后再分享一份终极手撕架构的大礼包(学习笔记):分布式+微服务+开源框架+性能优化
[外链图片转存中…(img-HL6AimbN-1712688558602)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!