拦截器配置(HandlerInterceptor)
一般情况下,对来自浏览器的请求的拦截,是利用Filter实现的。而在Spring中,基于Filter这种方式可 以实现Bean预处理、后处理。 比如注入FilterRegistrationBean,然后在这个Bean上传递自己继承 Filter实现的自定义Filter进入即可。 而Spring MVC也有拦截器,不仅可实现Filter的所有功能,还可以更精确的控制拦截精度。 Spring MVC 提供的org.springframework.web.servlet.handler.HandlerInterceptor这个适配器,实现此接口就可以可以 实现自己的拦截器。
- Filter和Interceptor的区别:
- Filter依赖Servlet容器,而Interceptor不依赖于Servlet容器
- Filter是基于函数回调(doFilter()方法)的,而Interceptor则是基于Java反射的(AOP思 想)。
- Filter对几乎所有的请求起作用,而Interceptor只能对action请求起作用。
- Interceptor可以访问Action的上下文,值栈里的对象,而Filter不能。
- 在action的生命周期里,Interceptor可以被多次调用,而Filter针对一个请求只会被调用一次。
- Filter在过滤是只能对request和response进行操作,而interceptor可以对request、 response、handler、modelAndView、exception进行操作。
package org.springframework.web.servlet
public interface HandlerInterceptor {
/* 预处理回调方法,实现处理器的预处理(例如登录校验) 第三个参数为响应的处理器,一般是自定 义的Controller
返回值:true 表示继续流程,如调用下一个拦截器或者是处理器;false表示流程中断,不会再 调用其他的响应器或者处理器 */
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; }
/* 后处理回调方法,实现处理器的后处理(但是在渲染视图之前),此时我们可以通过 ModelAndView对模型数据进行处理或者对视图进行处理。*/
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
/* 整个请求处理完毕回调方法,即在视图渲染完毕时回调,比如性能监控中我们可以在此记录结束时 间并输出消耗时间
还可以进行一些资源的清理,类似于try...catch...finally中的finally。 */
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
代码实现
/*** 自定义拦截器 */
@Component
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor...preHandle.........");
return true;
}
}
// 定义配置类,使拦截器生效
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private MyInterceptor myInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor).
// ** 表示拦截所有的请求
addPathPatterns("/**");
}
}
tk-Mybatis
TK-Mybatis是一个在Mybatis基础之上只做增强,不做改变的工具。为简化开发,提高效率而生。
导包
<!--Mysql连接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<!--Mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<!--durid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.16</version>
</dependency>
<!--tk-Mybatis-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
配置
数据源配置
spring:
datasource:
url: jdbc:mysql://localhost:3316/test
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
代码配置
配置实体类和表的映射
@Table(name = "user") // name配置为表名
public class User {
@Id
private Integer id; // @Id 表示该字段是主键
@Column
private String name; // @Column表示该字段是普通字段
@Column
private Integer age;
@Column
private String gender;
}
配置Mapper
public interface UserMapper extends Mapper<User> {
}
配置扫描包
@MapperScan(basePackages = "tkdemo.dal") //这个注解加到启动类上或者是 配置类上
public class TkDemoApplication {
}
测试
@Autowired
private UserService userService;
@Test
public void test01(){
// 这个就是tkMybatis给我们提供的模板方法,类似的方法还有很多
User user = userService.selectById(1);
System.out.println(user);
}
MapStruct
在一个成熟的工程中,尤其是现在的分布式系统中,应用与应用之间,还有单独的应用细分模块之后, DO一般不会让外部依赖,这时候需要在提供对外接口的模块里放 DTO用于对象传输,也即是 DO对象 对内,DTO对象对外,DTO 可以根据业务需要变更,并不需要映射 DO 的全部属性。
- DTO : Data Transport Object (数据传输对象)
- VO: View Object
导包
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>1.3.0.Final</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.0.Final</version>
</dependency>
</dependencies>
定义转换器接口
@Mapper(componentModel = "spring")
public interface UserConverter {
}
SPI
SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制。 目前有不少框架用它来 做服务的扩展发现(Dubbo、JDBC等), 简单来说,它就是一种动态替换发现的机制, 举个例子来 说, 有个接口,想运行时动态的给它添加实现,你只需要添加一个实现。
- Java SPI的约定(约定俗成)
- 当服务的提供者提供了服务接口的一种实现之后,在jar包的META-INF/Services/目录中同时创建 一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个 模块的时候,就能通过该jar包META-INF/Services/的配置文件找到具体的实现类名。并装载实例 化,完成模块的注入。基于这样的一个约定就能很好的找到服务接口的实现类,而不需要在代码里指定。
实践
- 定义接口
public interface CatService {
void sleep();
}
- 定义接口实现
public class BlackCatService implements CatService {
@Override
public void sleep() {
System.out.println("休息");
}
}
public class WhiteCatService implements CatService {
@Override
public void sleep() {
System.out.println("撸代码");
}
}
- 定义配置文件
在src/META-INF/services目录下新增和接口全类名一样的一个文件,文件里面配置需要接口动态 加载的实现类的全类名,这样Java在调用接口的时候就能动态的去找到接口的实现,而对原来的代 码没有丝毫的侵入性。
- 测试
public static void main(String[] args) {
ServiceLoader<CatService> serviceLoader = ServiceLoader.load(CatService.class);
serviceLoader.forEach(service ->{
service.sleep();
});
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/181105.html