首页
关于
友链
统计
Search
1
wlop 4K 壁纸 4k8k 动态 壁纸
1,041 阅读
2
Nacos持久化MySQL问题-解决方案
670 阅读
3
Docker搭建Typecho博客
659 阅读
4
keytool证书导入
541 阅读
5
滑动时间窗口算法
540 阅读
解决方案
JAVA基础
JVM
多线程
开源框架
数据库
前端
分布式
框架整合
中间件
容器部署
设计模式
数据结构与算法
开发工具
百度网盘资源
天翼网盘资源
阿里网盘资源
登录
Search
标签搜索
java
javase
docker
java8
springboot
thread
spring
分布式
mysql
锁
linux
redis
源码
typecho
centos
git
map
RabbitMQ
lambda
stream
少年
累计撰写
189
篇文章
累计收到
14
条评论
首页
栏目
解决方案
JAVA基础
JVM
多线程
开源框架
数据库
前端
分布式
框架整合
中间件
容器部署
设计模式
数据结构与算法
开发工具
百度网盘资源
天翼网盘资源
阿里网盘资源
页面
关于
友链
统计
搜索到
4
篇与
的结果
2022-09-15
JAVA8-Optional API
Optional API一、Optional创建方式前置条件:Insurance对象:public class Insurance { private String name; public String getName() { return name; } }1、empty特点:使用get()方法时会抛出异常:No value present范例:Optional<Insurance> emptyOptional = Optional.<Insurance>empty();使用get()获取结果:抛出异常emptyOptional.get();输出结果:Exception in thread "main" java.util.NoSuchElementException: No value present at java.base/java.util.Optional.get(Optional.java:148)2、of特点:使用get(),不会抛异常范例:Optional<Insurance> ofInsurance = Optional.of(new Insurance()); ofInsurance.get();3、ofNullable特点:上面两者综合,为null是掉empty,不为空调of。3.1、为null时,调get()抛出异常范例: Optional<Insurance> ofNullableOptionalNull = Optional.ofNullable(null); ofNullableOptionalNull.get();输出结果:Exception in thread "main" java.util.NoSuchElementException: No value present3.2、不为null时,调get()不报错范例: Optional<Insurance> ofNullableOptionalNotNull = Optional.ofNullable(new Insurance()); ofNullableOptionalNotNull.get();二、orElseGet、orElse、orElseThrow不管那种方式创建,都适用这几个方法。1、orElseGet说明:不为null就返回值,为null返回一个构造的对象supplier范例:Insurance orElseGetInsurance = ofNullableOptionalNull.orElseGet(Insurance::new); System.out.println(orElseGetInsurance);2、orElse说明:不为null就返回值,否则返回一个引用范例:Insurance orElseInsurance = ofNullableOptionalNull.orElse(new Insurance()); System.out.println(orElseInsurance);3、orElseThrow说明:不为null就返回值,否则返回一个异常对象范例:Insurance orElseThrowInsurance = ofNullableOptionalNull.orElseThrow(RuntimeException::new);输出结果:抛出运行时异常Exception in thread "main" java.lang.RuntimeException at java.base/java.util.Optional.orElseThrow(Optional.java:408)4、orElseThrow说明:不为null就返回值,否则返回一个自定义异常对象范例:ofNullableOptionalNull.orElseThrow(() -> new RuntimeException("yanxizhu Exception"));输出结果:抛出自定义异常Exception in thread "main" java.lang.RuntimeException: yanxizhu Exception三、filter先判断传入predicate是否null,让然后判断predicate传入字段是否存在,不存在:返回this。存在:判断predicate条件是否成立,成立:返回this,不成立:返回空。源码: public Optional<T> filter(Predicate<? super T> predicate) { //1、判断传入参数predicate是否为null Objects.requireNonNull(predicate); //2、判断t.getName是否存在, if (!isPresent()) { //2.1、不存在,返回predicate return this; } else { //2.2、存在:判断predicate条件是否成立,成立返回this,不成立返回empty() return predicate.test(value) ? this : empty(); } }requireNonNull()源码:判断传入T是否为null public static <T> T requireNonNull(T obj) { if (obj == null) throw new NullPointerException(); return obj; }范例:使用前创建Optional对象:1、创建Optinal,get()会抛出异常 Optional<Insurance> emptyOptional = Optional.<Insurance>empty(); 2、of创建,get(),不会抛异常 Optional<Insurance> ofInsurance = Optional.of(new Insurance()); 3、ofNullable:上面两者综合 3.1、为null时,调get()抛出异常:No value present Optional<Insurance> ofNullableOptionalNull = Optional.ofNullable(null); 3.2、不为null时,调get()不报错 Optional<Insurance> ofNullableOptionalNotNull = Optional.ofNullable(new Insurance());使用demo1: Optional<Insurance> insurance = emptyOptional.filter(t -> t.getName() == null); Optional<Insurance> insurance = emptyOptional.filter(t -> t.getName() != null); insurance.get();结果://调用get(),都会报错:No value present: 因为name字段不存在使用demo2:范例1:Optional<Insurance> insurance = ofInsurance.filter(t -> t.getName() == null); insurance.get(); 结果://不报错,因为name字段存在,且满足name==null范例2:Optional<Insurance> insurance = ofInsurance.filter(t -> t.getName() != null); insurance.get(); 结果://报错,因为name虽然存在,但是name!=null,不成立,会返回empty空,使用get()时就会抛出异常:No value present使用demo3: Optional<Insurance> insurance = ofNullableOptionalNull.filter(t -> t.getName() != null); Optional<Insurance> insurance = ofNullableOptionalNull.filter(t -> t.getName() == null); insurance.get();结果://都报错:ofNullableOptional,会走empty创建的Optional,字段不存在,直接get获取值为空,报错:No value present使用demo4:范例1:Optional<Insurance> insurance = ofNullableOptionalNotNull.filter(t -> t.getName() == null); insurance.get(); 结果://不会报错,走of方法创建的Optional,name字段存在,且name==null,所以不报错范例2:Optional<Insurance> insurance = ofNullableOptionalNotNull.filter(t -> t.getName() != null); insurance.get(); 结果://报错,因为虽然name存在,但是name!=null不成立,返回empty,get()就报错了filter,总结:使用时不确定是否为empty,所以直接使用ofNullableOptional创建Optional.四、map使用任何方式创建的Opional,map会将结果再包装成Optionla。范例: //map使用 Optional<String> stringOptional = ofNullableOptionalNotNull.map(t -> t.getName()); //有值则返回,没值则返回给定值 System.out.println(stringOptional.orElse("-1")); //判断值是否存在 System.out.println(stringOptional.isPresent()); //存在值,则打印输出,没有值,不打印。 stringOptional.ifPresent(System.out::println);五、flatMap不会将结果再包装成Optional范例:前置条件 @Data public class Cat { private Optional<Eat> eat; } @Data public class Eat { private String foodName; private Integer weight; }使用: //创建Optional对象 Optional<Cat> cat = Optional.ofNullable(new Cat()); //map将结果包装成Optional Optional<Optional<Eat>> eat = cat.map(c -> c.getEat()); //flatMap不会 Optional<Eat> eat1 = cat.flatMap(c -> c.getEat());map与flatMap区别:map将结果包装成Optional,flatMap不会。六、实列实列1、获取值之前判断值是否为空 public static String getInsuranceName(Insurance insurance) { Optional<String> optional = Optional.ofNullable(insurance).map(Insurance::getName); return optional.orElse("-1"); }实列2、根据用户拿到保险名字package com.example.study.java8.optional; import java.util.Optional; /** * 根据用户拿到保险名字 */ public class NullPointerException { public static void main(String[] args) { //肯定会包空指针异常 // String insuranceNameByPerson = getInsuranceNameByPerson(new Person()); //原始写法,做了空指针判断 String insuranceNameByCheckPerson = getInsuranceNameByCheckPerson(new Person()); // System.out.println(insuranceNameByCheckPerson); //Opional写法 String insuranceNameByOptional = getInsuranceNameByOptional(null); System.out.println(insuranceNameByOptional); } //Opional写法 public static String getInsuranceNameByOptional(Person person) { return Optional.ofNullable(person) .map(Person::getCar) .map(Car::getInsurance) .map(Insurance::getName) .orElse("-1"); } //flatMap不会把结果包装成Optional,map会。 //原始写法判断 public static String getInsuranceNameByCheckPerson(Person person) { if(null != person) { if(null != person.getCar()) { Car car = person.getCar(); if (null != car) { Insurance insurance = car.getInsurance(); if (null != insurance) { return insurance.getName(); } } } } return "UNKNOWN"; } public static String getInsuranceNameByPerson(Person person){ return person.getCar().getInsurance().getName(); } }
2022年09月15日
105 阅读
0 评论
3 点赞
2022-09-11
JAVA8-Stram练手
JAVA8-Stram练手交易员对象:package com.example.study.java8.streams.demo; /** * 交易员 */ public class Trader { private final String name; private final String city; public Trader(String n, String c){ this.name = n; this.city = c; } public String getName(){ return this.name; } public String getCity(){ return this.city; } public String toString(){ return "Trader:"+this.name + " in " + this.city; } } 交易对象package com.example.study.java8.streams.demo; /** * 交易 */ public class Transaction { private final Trader trader; private final int year; private final int value; public Transaction(Trader trader, int year, int value){ this.trader = trader; this.year = year; this.value = value; } public Trader getTrader(){ return this.trader; } public int getYear(){ return this.year; } public int getValue(){ return this.value; } public String toString(){ return "{" + this.trader + ", " + "year: "+this.year+", " + "value:" + this.value +"}"; } } 需求说明:1、交易年未2011年,并按交易金额排序2、获取城市并去重3、获取交易员所在城市为“Cambridge”的交易员,去重,并按交易员名字排序4、获取所有交易员名字,并排序,拼接成字符串5、交易员城市是否有在Milan的6、打印所有交易值,且交易员所在城市是Milan的7、找最大的值8、找最小的值需求实现范例:package com.example.study.java8.streams.demo; import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Optional; import static java.util.stream.Collectors.toList; /** * 交易员进行交易 */ public class StreamInAction { public static void main(String[] args) { Trader raoul = new Trader("Raoul", "Cambridge"); Trader mario = new Trader("Mario", "Milan"); Trader alan = new Trader("Alan", "Cambridge"); Trader brian = new Trader("Brian", "Cambridge"); List<Transaction> transactions = Arrays.asList( new Transaction(brian, 2011, 300), new Transaction(raoul, 2012, 1000), new Transaction(raoul, 2011, 400), new Transaction(mario, 2012, 710), new Transaction(mario, 2012, 700), new Transaction(alan, 2012, 950) ); //1、交易年未2011年,并按交易金额排序 transactions.stream() .filter(t -> t.getYear() == 2011) .sorted(Comparator.comparing(Transaction::getValue)) .collect(toList()) .forEach(System.out::println); System.out.println("==================================="); //2、获取城市并去重 transactions.stream() .map(t -> t.getTrader().getCity()) .distinct() .forEach(System.out::println); System.out.println("==================================="); //3、获取交易员所在城市为“Cambridge”的交易员,去重,并按交易员名字排序 transactions.stream() .map(t->t.getTrader()) .filter(g->"Cambridge".equals(g.getCity())) .distinct() .sorted(Comparator.comparing(Trader::getName)) .forEach(System.out::println); System.out.println("==================================="); //4、获取所有交易员名字,并排序,拼接成字符串 String result = transactions.stream() .map(t -> t.getTrader().getName()) .distinct() .sorted() .reduce("", (str1, str2) -> str1 + "\t" +str2); System.out.println(result); System.out.println("==================================="); //5、交易员城市是否有在Milan的 boolean anyMatch = transactions.stream() .anyMatch(t -> "Milan".equals(t.getTrader().getCity())); System.out.println(anyMatch); //或者 System.out.println("==================================="); boolean anyMatchMap = transactions.stream() .map(t -> t.getTrader()) .anyMatch(n -> "Milan".equals(n.getCity())); System.out.println(anyMatchMap); System.out.println("==================================="); //6、打印所有交易值,且交易员所在城市是Milan的。 transactions.stream() .filter(t->"Cambridge".equals(t.getTrader().getCity())) .map(Transaction::getValue) .sorted() .forEach(System.out::println); //7、找最大的值 System.out.println("==================================="); Optional<Integer> maxValue = transactions.stream() .map(Transaction::getValue) .reduce((i, j) -> i > j ? i : j); System.out.println(maxValue.get()); //8、找最小的值 System.out.println("==================================="); Optional<Integer> minValue = transactions.stream().map(t -> t.getValue()).reduce(Integer::min); System.out.println(minValue.get()); } }
2022年09月11日
87 阅读
0 评论
1 点赞
2022-09-07
JAVA8-Stream API
二、Stream API:filter、distinct、skip、limit被操作数据List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,6,5,4,3,2,1);1、filter 过滤范例://filter 过滤 List<Integer> filterResult = list.stream().filter(i -> i % 2 == 0).collect(toList()); filterResult.stream().forEach(System.out::println);2、distinct 去重范例: //distinct 去重 List<Integer> distinctResult = list.stream().distinct().collect(toList()); distinctResult.stream().forEach(System.out::println);3、skip 截断范例: //skip 截断(跳过前面几个,超过长度,直接返回空) List<Integer> skipResult = list.stream().skip(5).collect(toList()); skipResult.stream().forEach(System.out::println);4、limit 查询几条范例: //limit 查询几条 List<Integer> limitResult = list.stream().limit(3).collect(toList()); limitResult.stream().forEach(System.out::println);二、Stream API:Map1、map 数据处理被操作数据List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,6,5,4,3,2,1); List<Dish> menu = Arrays.asList( new Dish("pork", false, 800, Dish.Type.MEAT), new Dish("beef", false, 700, Dish.Type.MEAT), new Dish("chicken", false, 400, Dish.Type.MEAT), new Dish("french fries", true, 530, Dish.Type.OTHER), new Dish("rice", true, 350, Dish.Type.OTHER), new Dish("season fruit", true, 120, Dish.Type.OTHER), new Dish("pizza", true, 550, Dish.Type.OTHER), new Dish("prawns", false, 300, Dish.Type.FISH), new Dish("salmon", false, 450, Dish.Type.FISH)); String[] arrays = {"Hello","world"};范例1: //1、map List<Integer> mapResult = list.stream().map(i -> i * 2).collect(toList()); mapResult.stream().forEach(System.out::println);范例2: //2、map menu.stream().map(Dish::getName).forEach(System.out::println);范例3://3、flatMap 扁平化 //拆分成String[]: {h,e,l,l,o},{w,o,r,l,d} Stream<String[]> splitStream = Arrays.stream(arrays).map(s -> s.split("")); //flatMap扁平化,将{h,e,l,l,o},{w,o,r,l,d}每个数组转成Stream<String> Stream<String> stringStream = splitStream.flatMap(Arrays::stream); stringStream.distinct().forEach(System.out::println);打印结果:H e l o w r d三、Stream API:Match1、Match匹配范例:1.1、allMatch 全部满足条件 Stream<Integer> list = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); //1、allMatch 全部满足条件 boolean booleanAnyMath = list.allMatch(i -> i > 0); System.out.println(booleanAnyMath);1.2、anyMatch 任意一个满足条件 //2、anyMatch 任意一个满足条件 list = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); boolean anyMatch = list.anyMatch(i -> i > 9); System.out.println(anyMatch);1.3、noneMatch 没有一个满足 //3、noneMatch 没有一个满足 list = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); boolean noneMatch = list.noneMatch(i -> i == 11); System.out.println(noneMatch);四、Stream API:find2、find查找范例:2.1、findFirst 查找第一个 //1、findFirst 查找第一个 Optional<Integer> firstOptional = stream.filter(i -> i % 2 == 0).findFirst(); System.out.println(firstOptional); ```` **2.2、findAny 查找任意一个** stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); Optional<Integer> anyOptional = stream.filter(i -> i % 2 == 0).findAny(); System.out.println(anyOptional.get()); **2.3、没找到时,使用get()会直接抛出异常提示信息,会提示错误:No value present** ```java stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); Optional<Integer> noNumOptional = stream.filter(i -> i == 11).findAny(); System.out.println(noNumOptional.get());抛出异常提示: //抛出异常提示:No value present ```` **2.4、没找到时,Optional输出:Optional.empty,不抛异常** System.out.println(noNumOptional); *输出结果:*Optional.empty **3、orElse 如果没查找返回给定的值** 范例: **需求:查询数组中是否包含指定值,没有返回默认值。** ***3.1、原始写法*** 先写个方法,然后调用/* * 原始写法,查询数组中是否包含指定值,没有返回默认值 * @param values * @param defaultValue * @param predicate * @return */ public static int findDifineValue(Integer[] values, int defaultValue, Predicate<Integer> predicate){ for(int i : values){ if(predicate.test(i)){ return i; } } return defaultValue; } 调用原始写法: int findValueResult = findDifineValue(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, -1, i -> i == 9); System.out.println(findValueResult); ***3.2、orElse写法*** // orElse写法 如果没查找返回给定的值 stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); Optional<Integer> noNumOptional = stream.filter(i -> i == 11).findAny(); System.out.println(noNumOptional.orElse(-1));比原始写法简写很多。 ---------- **4、isPresent 判断是否存在,直接返回boolean值** stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); boolean isPresent = stream.filter(i->i==4).findAny().isPresent(); System.out.println(isPresent); **5、存在就打印出来,没有则不打印** stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); stream.filter(i->i==6).findAny().ifPresent(System.out::println); ** 6、还可以进行二次过滤** stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); //先Stream的filter过滤,然后得到Optional,再用Optional的filter过滤 stream.filter(i->i>8).findAny().filter(i->i<10).ifPresent(System.out::println);## 五、Stream API:reduce:聚合作用,根据reduce传入的Function条件进行聚合 ![reduce](https://cdn.jsdelivr.net/gh/willxwu/CDN@main/images/202209081919342.png) 范例:package com.example.study.java8.streams;import java.util.Arrays;import java.util.List;/**Stream reduce:聚合作用,根据reduce传入的Function条件进行聚合用法:只要reduce里面参数满足funcion就可以 */public class StreamReduce {public static void main(String[] args) { //用法:只要reduce的参数满足Function就可以 //reduce(0, (i, j) -> i + j) List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,6,5,4,3,2,1); Integer reduceResult = list.stream().reduce(0, (i, j) -> i + j); System.out.println(reduceResult); System.out.println("==================================="); //reduce((i,j)->i+j) list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,6,5,4,3,2,1); list.stream().reduce((i,j)->i+j).ifPresent(System.out::println); System.out.println("==================================="); //reduce(Math::max) list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,6,5,4,3,2,1); list.stream().reduce(Math::max).ifPresent(System.out::println); System.out.println("==================================="); //reduce(Integer::sum) list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,6,5,4,3,2,1); list.stream().reduce(Integer::sum).ifPresent(System.out::println); }}
2022年09月07日
126 阅读
0 评论
5 点赞
2022-04-23
线程封闭
线程封闭当访问共享数据时,通常是要使用同步。如果要避免使用同步,就是不提供共享数据。如果仅在单线程中访问数据,就不需要同步,这种技术就叫做线程封闭,它是实现线程安全最简单的方式之一。当某个对象封闭在一个线程当中时将自动实现线程安全性,即使被封闭的对象本身它并不是安全的,实现线程主要有三种方式。实现线程封闭的三种方式:1、Ad-hoc线程封闭:程序控制实现,最糟糕,忽略2、堆栈封闭:局部变量,无并发问题:栈封闭简单理解就是通过局部变量来实现线程封闭,多个线程访问对象的同一个方法,方法内部的局部变量会拷贝到每个线程的线程栈当中,只有当前线程才能访问到,互不干扰。所以局部变量是不被多个线程所共享的。尽量少用全局变量(不是全局常量)。3、ThreadLocal线程封闭:特别好的封闭方法。维护线程封闭一种更规范的方法就是使用ThreadLocal。ThreadLocal底层是一个map,可以就是线程名字,value就是我们封装的对象。ThreadLocal提供get、set方法为每个使用该变量的线程都存有一份独立的副本,因此get总是返回的是当前线程在调用set时设置的值。ThreadLocal一般用于防止对可变的单实例变量或者全局变量进行共享。ThreadLocal使用:代码示例1、自定义ThreadLoca工具package com.yanxizhu.demo.concurrency.DemoThrodLocal.ThreadLock; /** * @description: 使用ThrodLock的线程封闭,实现在一个线程种数据共享 * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/4/22 22:56 * @version: 1.0 */ public class MyThroldLock { private final static ThreadLocal<Long> requestholder = new ThreadLocal<>(); //用ThreadLock提供的set方法,向ThreadLock中放入共享数据id //一般在实际接口处理前调用 public static void add(Long id) { requestholder.set(id); } //用ThreadLock提供的get方法获取ThreadLock中共享的数据 public static Long get() { return requestholder.get(); } //用ThreadLock提供的remove方法移除共享数据,不然容易导致内存溢出 //一般在接口真正处理完后调用 public static void remove() { requestholder.remove(); } }2、自定义过滤器Filterpackage com.yanxizhu.demo.concurrency.DemoThrodLocal.filter; import com.yanxizhu.demo.concurrency.DemoThrodLocal.ThreadLock.MyThroldLock; import lombok.extern.slf4j.Slf4j; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @description: 自定一自己的filter,实现filter接口,注意是servlet中的 * 说明: * Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序, * 主要的用途是设置字符集、控制权限、控制转向、做一些业务逻辑判断等。其工作原理是, * 只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求, * 此时你就可以对请求或响应(Request、Response)统一设置编码,简化操作; * 同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。 * 它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。 * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/4/22 23:02 * @version: 1.0 */ @Slf4j public class HttpFilter implements Filter { //初始化的 public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { //一般需要强转成HttpServletRequest、HttpServletResponse,这样才能直接获取用户浏览器访问时携带信息 //比如获取用户session中的用户信息 HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; //一般登录会将用户信息写入session,这里只是演示一下 // String userName = (String) request.getSession().getAttribute("userName"); log.info("do filter,线程id {},请求地址{}", Thread.currentThread().getId(), request.getServletPath()); //通过向ThreadLock添加共享值 MyThroldLock.add(Thread.currentThread().getId()); // 所有处理完后,记得执行下面,不然不会往下执行 filterChain.doFilter(servletRequest, servletResponse); } //销毁时的 public void destroy() { } }注册自定义过滤器HttpFilterpackage com.yanxizhu.demo.concurrency.DemoThrodLocal.filter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @description: 将自定义的filter添加到spring拦截器中 * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/4/22 23:37 * @version: 1.0 */ @Configuration public class MyFilterConfig { @Bean public FilterRegistrationBean httpFilter() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(new HttpFilter()); filterRegistrationBean.addUrlPatterns("/demo/*"); return filterRegistrationBean; } }3、自定义拦截器HandlerInterceptorpackage com.yanxizhu.demo.concurrency.DemoThrodLocal.interceptor; import com.yanxizhu.demo.concurrency.DemoThrodLocal.ThreadLock.MyThroldLock; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @description: 自定义HandlerInerceptor * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/4/22 22:28 * @version: 1.0 */ @Slf4j @Component public class MyHandlerInterceptor implements HandlerInterceptor { //接口处理之前 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("进入controller之前的preHanler方法。。。。"); return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("这个是干嘛的呢。。。"); } //接口处理之后 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("之后的方法。。。。afterCompletion,MyThroldLock.remove()"); MyThroldLock.remove(); return; } }注册自定义拦截器MyHandlerInterceptorpackage com.yanxizhu.demo.concurrency.DemoThrodLocal.interceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @description: 自定义WebMVCConfig * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/4/22 22:31 * @version: 1.0 */ @Configuration public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer { @Autowired MyHandlerInterceptor myHandlerInterceptor; public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myHandlerInterceptor).addPathPatterns("/**"); } }4、编写Controller测试ThreadLock的使用package com.yanxizhu.demo.concurrency.DemoThrodLocal.controller; import com.yanxizhu.demo.concurrency.DemoThrodLocal.ThreadLock.MyThroldLock; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @description: HandlerInterceptor 拦截器测试 * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/4/22 22:25 * @version: 1.0 */ @RestController @RequestMapping("/demo") @Slf4j public class ThreadLockController { @GetMapping("/myHandlerInterceptor") public String myHandlerInterceptorTest() { log.info("进入Controoler方法种。。。。。。"); return "My HandlerInterceptor....,共享ThreadLock的变量为:"+MyThroldLock.get(); } }测试请求地址http://127.0.0.1:8080/demo/myHandlerInterceptor页面输出结果:My HandlerInterceptor....,共享ThreadLock的变量为:46IDEA控制台输出结果:do filter,线程id 50,请求地址/demo/myHandlerInterceptor 进入controller之前的preHanler方法。。。。 进入Controoler方法种。。。。。。 这个是干嘛的呢。。。 之后的方法。。。。afterCompletion注意点注意过滤器Filter和拦截器HandlerInterceptor的区别及使用方式。可参考地址:https://blog.csdn.net/yb546822612/article/details/102950040https://blog.csdn.net/yb546822612/article/details/102950981
2022年04月23日
155 阅读
0 评论
3 点赞