目录
一:Springboot中自定义组件
1、@configuration+@bean注入组件
2、@Controller @Service @Repository @Component注入组件
3、另外也可用@Import注册组件,但是要放在标有
4、根据条件注册组件
二:Springboot中三大组件(拦截器、过滤器、监听器)及aop、异常处理配置
1、概述
2、过滤器
无路径无顺序@Component
@WebFilter+@ServletComponentScan
@Configuration+FilterRegistrationBean
3、监听器
4、拦截器
5、aop
6、全局异常处理器
三:扩展mvc配置
Springboot1.x版本如何配置
Springboot2.x版本如何配置
四:tomcat配置
一:Springboot中自定义组件
1、@configuration+@bean注入组件
spring是是通过xml给容器添加组件的,在Springboot可以通过@configuration配置类的方式添加组件
@Configuration //告诉boot这是一个配置类,相当于Spring中的配置文件
public class MyConfig {
/**
*1、通过配置类给容器添加组件 方法名作为组件的id返回类型就是组件的类型 返回的值就是组件在容器中的实列
*2、如果不想让方法名作为组件id 可以在bean注解中传参
*3、无论对这个方法调用多少次 获取到的都是之前注册进容器中的单实例对象
* @Bean("testUser")
*/
@Bean
public User demoUser(){
return new User("回去吧三哥",18);
}
}
查看容器中注入的组件
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
//返回我们的容器
ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
//2.查看容器里的组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
}
fastJsonpResponseBodyAdvice
demoUser
restTemplate
simpleClientHttpRequestFactory
org.springframework.boot.autoconfigure.AutoConfigurationPackages
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
propertySourcesPlaceholderConfigurer
并且我们注入的组件在容器中是单例的,测试如下
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
//返回我们的容器
ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
//精确获取组件
User user1 = run.getBean("demoUser", User.class);
User user2 = run.getBean("demoUser", User.class);
System.out.println(user1==user2);//打印true
}
}
注意:配置类本身也是一个组件
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
//返回我们的容器
ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
//精确获取组件
MyConfig myConfig = run.getBean(MyConfig.class);
System.out.println(myConfig);
//使用
User user = myConfig.demoUser();
System.out.println(user);
}
}
com.common.config.MyConfig$$EnhancerBySpringCGLIB$$3ef8885e@1999e1f5
com.user.User@b1fa523
boot2版本对于Configuration注解新增了一个属性proxyBeanMethods,默认是true;会使用代理对象调用组件方法,boot总会检查容器中是否有这个容器,即保持组件单实例
@Configuration(proxyBeanMethods = true)
public class MyConfig {
@Bean
public User demoUser(){
return new User("回去吧三哥",18);
}
}
//打印true
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
MyConfig myConfig = run.getBean(MyConfig.class);
User user = myConfig.demoUser();
User user1 = myConfig.demoUser();
System.out.println(user==user1);//true
}
}
如果改为false
@Configuration(proxyBeanMethods = false)
public class MyConfig {
@Bean
public User demoUser(){
return new User("回去吧三哥",18);
}
}
//打印true
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
MyConfig myConfig = run.getBean(MyConfig.class);
User user = myConfig.demoUser();
User user1 = myConfig.demoUser();
System.out.println(user==user1);//false
}
}
上面两种方式就是boot2中的底层配置的两种方式,主要用来解决组件依赖,
Full(全配置),即增加proxyBeanMethods = true;如果注册的组件在别组件会用到,那就设置为true 保证单实例;
Lite(轻量级),即增加proxyBeanMethods = false;如果注册的组件在别组件不会用到,那就设置为false 减少判断 加快启动
2、@Controller @Service @Repository @Component注入组件
除了上面的@Configuration+@bean方式给容器注入一个组件,还可使用@Controller @Service @Repository @Component结合@bean注入组件
3、另外也可用@Import注册组件,但是要放在标有
@Configuration、@Controller、 @Service、 @Repository、 @Component注解标识的类上
@Import({User.class})
@Configuration
public class MyConfig {
public User demoUser(){
return new User("回去吧三哥",18);
}
}@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
//返回我们的容器
ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
String[] beans = run.getBeanNamesForType(User.class);
for (String name : beans) {
System.out.println(name);//com.user.User
}
}
}
4、根据条件注册组件

案例一:用在方法上
@Configuration
public class MyConfig {
@ConditionalOnBean(name = "tom")//只有容器中有tom这个组件,才会注入demoUser组件
@Bean
public User demoUser(){
return new User("回去吧三哥",18);
}
}
案例二:用在类上
@Configuration
@ConditionalOnBean(name = "tom")//只有容器中有tom这个组件,才会注入demoUser组件和testUser组件
public class MyConfig {
@Bean
public User demoUser(){
return new User("回去吧三哥",18);
}
@Bean
public User testUser(){
return new User("回去吧三哥",18);
}
}
二:Springboot中三大组件(拦截器、过滤器、监听器)及aop、异常处理配置
1、概述
过滤器、拦截器、监听器、AOP、全局异常处理器是搭建系统框架时,经常用到的部分,全局异常处理器的作用很明显,就是处理接口执行过程中的异常,而过滤器、拦截器和AOP的作用就很丰富了,日志记录、性能监控、安全认证等等可以向上抽取的功能组件,均可以用他们来实现。
传统基于Servlet容器的程序中,我们可以使用过滤器和监听器,在Java 框架中还可以使用拦截器,而面向切面编程AOP更是作为Spring框架中的核心思想被大家所关注
Filter和Listener:依赖Servlet容器,基于函数回调实现。可以拦截所有请求,覆盖范围更广,但无法获取ioc容器中的bean。
Interceptor和aop:依赖spring框架,基于java反射和动态代理实现。只能拦截controller的请求,可以获取ioc容器中的bean,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。。
从 Filter -> Interceptor -> aop ,拦截的功能越来越细致、强大,尤其是Interceptor和aop可以更好的结合spring框架的上下文进行开发。但是拦截顺序也是越来越靠后,请求是先进入Servlet容器的,越早的过滤和拦截对系统性能的消耗越少。具体选用哪种方法,就需要开发人员根据实际业务情况综合考虑了。
2、过滤器
Filter过滤器是Servlet容器层面的,在实现上基于函数回调,可以对几乎所有请求进行过滤。过滤器是对数据进行过滤,预处理过程,当我们访问网站时,有时候会发布一些敏感信息,发完以后有的会用*替代,还有就是登陆权限控制等,一个资源,没有经过授权,肯定是不能让用户随便访问的,这个时候,也可以用到过滤器,主要是对用户的一些请求进行一些预处理,并在服务器响应后再进行预处理,返回给用户。
过滤器的功能还有很多,例如实现URL级别的权限控制、压缩响应信息、编码格式等等。对web服务器管理所有的web资源,例如jsp,静态图片 过滤敏感词汇,某些信息用*隐藏。
springboot中有三种使用方式
无路径无顺序@Component
这种方式最简单,直接实现Filter接口,并使用@Component注解标注为组件自动注入bean。但是缺点是没办法设置过滤的路径,默认是 /* 过滤所有。
Filter接口有 init、doFilter、destroy 三个方法,但 init、destroy 是有默认方法实现,可以不重写。
@Component
public class TimeFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("=======初始化过滤器=========");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
long start = System.currentTimeMillis();
filterChain.doFilter(request, response);
System.out.println("filter 耗时:" + (System.currentTimeMillis() - start));
}
@Override
public void destroy() {
System.out.println("=======销毁过滤器=========");
}
}
这种方式看起来很方便,一个注解将 Filter 纳入到 Spring 容器中即可。而且这种方式还有一个优势,就是如果存在多个 Filter,可以通过 @Order 注解指定多个 Filter 的优先级,像下面这样:
@Component
@Order(-1)
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("-----doFilter-----");
chain.doFilter(request, response);
}
}
效果
2021-03-11 19:39:55.406 INFO o.a.c.core.ContainerBase.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2021-03-11 19:39:55.406 INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1336 ms
=======初始化过滤器=========
2021-03-11 19:39:55.514 INFO c.a.d.s.b.a.DruidDataSourceAutoConfigure - Init DruidDataSource
2021-03-11 19:39:55.686 INFO com.alibaba.druid.pool.DruidDataSource - {dataSource-1} inited
@WebFilter+@ServletComponentScan
通过 @WebFilter 注解来标记一个过滤器,这种方式相信大家很容易想到。这是将 Servlet 中的那一套东西直接拿到 Spring Boot 上用。
具体做法就是通过 @WebFilter 注解来标记一个 Filter,如下:
//一个是filter的名字,一个是url为什么时用此过滤器,其他的看源码,Filter,必须要有名字,所有的过滤器执行顺序是根据Filter的名字字母顺序来执行的
@WebFilter(filterName = "filter1",urlPatterns = {"/hello/*"})
public class TimeFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("=======初始化过滤器=========");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
long start = System.currentTimeMillis();
filterChain.doFilter(request, response);
System.out.println("filter 耗时:" + (System.currentTimeMillis() - start));
}
@Override
public void destroy() {
System.out.println("=======销毁过滤器=========");
}
}
这个注解要生效,还需要我们在项目启动类上配置 @ServletComponentScan 注解,
@ServletComponentScan 注解虽然名字带了 Servlet,但是实际上它不仅仅可以扫描项目中的 Servlet 容器,也可以扫描 Filter 和 Listener。
这是我们在 Spring Boot 中使用过滤器的第一种方式,在实际项目中,这种方式使用较少,因为这种方式有一个很大的弊端就是无法指定 Filter 的优先级,如果存在多个 Filter 时,无法通过 @Order 指定优先级。
@SpringBootApplication
@ServletComponentScan
public class SysoaApplication {
public static void main(String[] args) {
SpringApplication.run(SysoaApplication.class, args);
}
}
测试
2021-03-11 19:41:51.572 INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1325 ms
=======初始化过滤器=========
2021-03-11 19:41:51.692 INFO c.a.d.s.b.a.DruidDataSourceAutoConfigure - Init DruidDataSource
2021-03-11 19:41:51.847 INFO com.alibaba.druid.pool.DruidDataSource - {dataSource-1} inited
@Configuration+FilterRegistrationBean
还是将 Filter 封装成一个 Bean,但这个 Bean 是 FilterRegistrationBean,通过 FilterRegistrationBean 我们既可以配置 Filter 的优先级,也可以配置 Filter 的拦截规则。
public class AFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("=======初始化过滤器A=========");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
long start = System.currentTimeMillis();
filterChain.doFilter(request, response);
System.out.println("filter 耗时:" + (System.currentTimeMillis() - start));
}
@Override
public void destroy() {
System.out.println("=======销毁过滤器=========");
}
}@Configuration
public class myConfig {
@Bean
FilterRegistrationBean<AFilter> myFilterFilterRegistrationBean() {
FilterRegistrationBean<AFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new AFilter());
bean.setOrder(-1);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}
@Bean
FilterRegistrationBean<BFilter> myFilterFilterRegistrationBean2() {
FilterRegistrationBean<BFilter> bean = new FilterRegistrationBean<>();
bean.setFilter(new BFilter());
bean.setOrder(-2);
bean.setUrlPatterns(Arrays.asList("/hello"));
return bean;
}
}
FilterRegistrationBean 扩展
Spring Boot 为了方便大家向 Servlet 容器中注册 Servlet、Filter 以及 Listener,提供了一个 Bean 注册的抽象类 RegistrationBean,如下:
public abstract class RegistrationBean implements ServletContextInitializer, Ordered {
private int order = Ordered.LOWEST_PRECEDENCE;
private boolean enabled = true;
@Override
public final void onStartup(ServletContext servletContext) throws ServletException {
String description = getDescription();
if (!isEnabled()) {
logger.info(StringUtils.capitalize(description) + " was not registered (disabled)");
return;
}
register(description, servletContext);
}
protected abstract String getDescription();
protected abstract void register(String description, ServletContext servletContext);
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isEnabled() {
return this.enabled;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
} RegistrationBean 实现了 ServletContextInitializer 接口,在 Servlet 启动时,RegistrationBean#onStartup 方法会被调用,进而完成 Filter、Servlet 以及 Listener 的注册。
enabled 属性可以理解为一个开关,设置为 false 相当于关闭组件注册。
RegistrationBean 有众多的实现类,我们之前使用的 FilterRegistrationBean 只是其中之一:

实现类的作用一目了然:
ServletListenerRegistrationBean 用来注册监听器。
ServletRegistrationBean 用来注册 Servlet。
DispatcherServletRegistrationBean 用来注册 DispatcherServlet。
FilterRegistrationBean 用来注册过滤器。
DelegatingFilterProxyRegistrationBean 则用来注册 DelegatingFilterProxy,DelegatingFilterProxy 在 Spring Security、Spring Session、Shiro 等整合时非常有用。
3、监听器
Listener监听器也是Servlet层面的,可以用于监听Web应用中某些对象、信息的创建、销毁和修改等动作发生,然后做出相应的响应处理。可以在这些事件发生前和发生后进行处理。用途:1、用于统计在线人数和在线用户,2、系统启动时加载初始化信息,3、统计网站访问量,4、记录用户访问路径
根据监听对象,将监听器分为3类:
第一类:ServletContext:对应application,实现接口ServletContextListener。在整个Web服务中只有一个,在Web服务关闭时销毁。可用于做数据缓存,例如结合redis,在Web服务创建时从数据库拉取数据到缓存服务器。
第二类:HttpSession:对应session会话,实现接口HttpSessionListener。在会话起始时创建,一端关闭会话后销毁。可用作获取在线用户数量。
第三类:ServletRequest:对应request,实现接口ServletRequestListener。request对象是客户发送请求时创建的,用于封装请求数据,请求处理完毕后销毁。可用作封装用户信息。
在写Listener的类时,有两种方式。一种是只加@Component;另一种是 @WebListener 和 @ServletComponentScan 配合使用。不过实现接口则根据监听对象区分,如:ServletContextListener、HttpSessionListener和ServletRequestListener。
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener()
public class MyListener implements HttpSessionListener{
public static int online = 0;
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("创建session,在线用户数:" + (++online));
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("销毁session,在线用户数:" + (--online));
online--;
}
}
启动类
@SpringBootApplication
@ServletComponentScan("com.demo.listener") //需要扫描包
public class SpringBoot1Application {
public static void main(String[] args) {
SpringApplication.run(SpringBoot1Application.class, args);
}
}
这里我们再补充一下常用的监听器接口:
1.ServletContextListener -- 监听servletContext对象的创建以及销毁
1.1 contextInitialized(ServletContextEvent arg0) -- 创建时执行
1.2 contextDestroyed(ServletContextEvent arg0) -- 销毁时执行
2.HttpSessionListener -- 监听session对象的创建以及销毁
2.2 sessionCreated(HttpSessionEvent se) -- 创建时执行
2.2 sessionDestroyed(HttpSessionEvent se) -- 销毁时执行
3.ServletRequestListener -- 监听request对象的创建以及销毁
3.1 requestInitialized(ServletRequestEvent sre) -- 创建时执行
3.2 requestDestroyed(ServletRequestEvent sre) -- 销毁时执行
4.ServletContextAttributeListener -- 监听servletContext对象中属性的改变
4.1 attributeAdded(ServletContextAttributeEvent event) -- 添加属性时执行
4.2 attributeReplaced(ServletContextAttributeEvent event) -- 修改属性时执行
4.3 attributeRemoved(ServletContextAttributeEvent event) -- 删除属性时执行
5.HttpSessionAttributeListener --监听session对象中属性的改变
5.1 attributeAdded(HttpSessionBindingEvent event) -- 添加属性时执行
5.2 attributeReplaced(HttpSessionBindingEvent event) -- 修改属性时执行
5.3 attributeRemoved(HttpSessionBindingEvent event) -- 删除属性时执行
6.ServletRequestAttributeListener --监听request对象中属性的改变
6.1 attributeAdded(ServletRequestAttributeEvent srae) -- 添加属性时执行
6.2 attributeReplaced(ServletRequestAttributeEvent srae) -- 修改属性时执行
6.3 attributeRemoved(ServletRequestAttributeEvent srae) -- 删除属性时执行
4、拦截器
Interceptor拦截器和Filter和Listener有本质上的不同,前面二者都是依赖于Servlet容器,而Interceptor则是依赖于Spring框架,是aop的一种表现,当某个方法或字段被访问时进行拦截,在之前 和 在之后 加入某些操作,用途:权限验证,判断用户是否登录,或者再做某一操作时要确定满足某一定的条件,基于Java的动态代理实现的。在SpringBoot中实现拦截器的方式
- 声明拦截器的类:通过实现 HandlerInterceptor接口,实现preHandle、postHandle和afterCompletion方法。
- 通过配置类配置拦截器:通过实现WebMvcConfigurer接口,实现addInterceptors方法。
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 InterceptorTest implements HandlerInterceptor {
/**
* 在请求处理之前进行调用(Controller方法调用之前)
* 预处理回调方法,实现处理器的预处理
* 返回值:true表示继续流程;false表示流程中断,不会继续调用其他的拦截器或处理器
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("开始拦截.........");
String name = MyCookie.getCookieByKey(request,response,"name");
String password = MyCookie.getCookieByKey(request,response,"password");
//如果session中没有user,表示没登陆
if (password == null|| name == null){
//这个方法返回false表示忽略当前请求,如果一个用户调用了需要登陆才能使用的接口,如果他没有登陆这里会直接忽略掉
//当然你可以利用response给用户返回一些提示信息,告诉他没登陆
request.getRequestDispatcher("/interceptor/to_login").forward(request, response);
return false;
}else {
return true;//放行
}
}
/**
* 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
* 后处理回调方法,实现处理器(controller)的后处理,但在渲染视图之前
* 此时我们可以通过modelAndView对模型数据进行处理或对视图进行处理
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
System.out.println("return前");
}
/**
* 在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
* 整个请求处理完毕回调方法,即在视图渲染完毕时回调,
* 如性能监控中我们可以在此记录结束时间并输出消耗时间,
* 还可以进行一些资源清理,类似于try-catch-finally中的finally,
* 但仅调用处理器执行链中
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
System.out.println("操作完之后,可以用于资源清理");
}
}
然后将这个组件加入到boot中,在boot1版本中 通过继承WebmvcConfigureAdapter实现一个web配置,例如我们配置上面的拦截器
@Configuration //声明这是一个配置
public class LoginInterceptorConfig extends WebMvcConfigurerAdapter {
@Resource
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin").excludePathPatterns("/admin/login");
}
}
或者直接使用匿名类的方式
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义一个登陆拦截器
*/
@Configuration //声明这是一个配置
public class LoginInterceptor extends WebMvcConfigurerAdapter {
/*
用来添加拦截器的方法
InterceptorRegistry registry拦截器注册
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//使用匿名内部类创建要给拦截器
HandlerInterceptor loginInterceptor = new HandlerInterceptor() {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
//判断session中是否存在用户
if (request.getSession().getAttribute("user") == null) {
response.sendRedirect("/admin");
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
};
registry.addInterceptor(loginInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin").excludePathPatterns("/admin/login");
}
}
对于Sprinboot2版本,第一步还是定义一个拦截器组件
第二不再是通过继承WebmvcConfigureAdapter实现一个web配置,而是实现接口WebMvcConfigurer增加一个配置
@Configuration
public class WebConfig implements WebMvcConfigurer {
//引入我们的拦截器组件
@Resource
private LoginInterceptor loginInterceptor;
//实现拦截器配置方法
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor).addPathPatterns("/admin/**").excludePathPatterns("/admin").excludePathPatterns("/admin/login");
}
}
5、aop
相比较于拦截器,Spring 的aop则功能更强大,封装的更细致,需要单独引用 jar包。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
//当然引入web stater就不必单独引入aop
在定义AOP的类时,不需要和前面拦截器一样麻烦了,只需要通过注解,底层实现逻辑都通过IOC框架实现好了,涉及到的注解如下:
- @Aspect:将一个 java 类定义为切面类。
- @Pointcut:定义一个切入点,可以是一个规则表达式,比如下例中某个 package 下的所有函数,也可以是一个注解等。
- @Before:在切入点开始处切入内容。
- @After:在切入点结尾处切入内容。
- @AfterReturning:在切入点 return 内容之后处理逻辑。
- @Around:在切入点前后切入内容,并自己控制何时执行切入点自身的内容。原则上可以替代@Before和@After。
- @AfterThrowing:用来处理当切入内容部分抛出异常之后的处理逻辑。
- @Order(100):AOP 切面执行顺序, @Before 数值越小越先执行,@After 和 @AfterReturning 数值越大越先执行。
主要应用(记录日志和全局事务处理)地址如下
6、全局异常处理器
三:扩展mvc配置
Springboot在web层的开发基本都是采用Springmvc框架技术,但是Springmvc中的某些配置在boot是没有的,我们就应该根据自己的需求进行对mvc扩展配置
Springboot1.x版本如何配置
通过注解@Configuration一个类,继承webmvcconfigureradapter,然后根据需求实现里面的方法。

Springboot2.x版本如何配置
通过实现webmvcconfigure接口的方式
上面boot对mvc的扩展配置既保留了mvc的默认配置,也可以使用我们扩展的配置。如何全面接管mvc的配置,所以的webmvc都由我们自己配置?只需要加上注解EnableWebMvc

四:tomcat配置
Springboot默认使用的就是嵌入式servlet容器即tomcat,对于web项目,如果使用的是外部tomcat,相关配置比如访问端口、资源路径等可以在tomcat的conf文件下配置。但是在boot中,tomcat配置又两种方式
第一种:通过配置文件直接配置(推荐)
#如果是tomcat相关的设置用server.tomcat.xx
server.tomcat.uri-encoding=UTF-8
#如果是servlet相关的配置用server.xx
server.port=80
第二种:通过配置类的方式
