SpringBoot
Day01
1.1 什么是springBoot?
springBoot是一个能够让我们快速搭建庞大的spring项目,尽可能减少xml的配置,做到开箱即用,让我们关注业务而不是配置
1.2 javaConfig配置Ioc
普通的配置(使用@Bean)
定义两个Bean
@Setter@Getter
public SomeBean() {
System.out.println("SomeBean被创建");
}
public void init() {
System.out.println("SomeBean被初始化");
}
public void destroy() {
System.out.println("SomeBean被销毁");
}
}
public class OtherBean {
public OtherBean() {
System.out.println("OtherBean被创建");
}
}
对比我们以前使用xml配置,我们将xml的配置转移到类里来
在一个类上贴上 @Configuration注解,表示这是一个配置类,相当spring的一个xml文件
然后再里面进行bean的注入相当于之前的
/* @Configuration
* 贴有该注解的类表示Spring的配置类
* 用于替代传统的applicationContext.xml
*/
@Configuration
public class JavaConfig {
/**
* @Bean
* 该注解贴在配置类的方法上,该方法会被Spring容器自动调用
* 并且返回的对象交给Spring管理
* 相当于<bean id="someBean" class="cn.wolfcode.common.SomeBean"/>
*/
@Bean
public SomeBean someBean() {
return new SomeBean();
}
}
关于Bean的配置
@Bean注解中的属性
name: 对应bean标签中的name属性,用于给bean取别名
initMethod: 对应bean标签中的init-method属性,配置bean的初始化方法
destroyMethod: 对应bean标签中的destroy-method属性,配置bean的销毁方法
注意: 在配置类的方式中有许多的默认规定,比如:
bean的id就是当前方法名
配置多例则是在方法上添加@Scope("prototype")注解来实现,一般不用配,默认单例即可
进行测试
public class App {
@Test
public void testJavaConfig() {
//1:加载配置类,创建Spring容器
ApplicationContext ctx =
new AnnotationConfigApplicationContext(JavaConfig.class);
//2:从容器中取出SomeBean对象
SomeBean someBean = ctx.getBean(SomeBean.class);
System.out.println(someBean);
}
}
注解配置(使用注解)
@Component
@Setter@Getter
public class SomeBean {
}
@ComponentScan:扫描,不写扫描哪里表示扫描当前所在类的包及其子包
@Configuration //表示该类是Spring的配置类
@ComponentScan //开启组件扫描器,默认扫描当前类所在的包,及其子包
public class JavaConfig { }
1.3 SpringBoot的测试类
传统的xml
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:xml文件路径")
public class App { ... }
junit5的方式
springboot 2.2.x版本后默认使用junit5版本的测试包
@SpringBootTest(classes = xxxx.class) 表示读取对应的配置类,想当于之前的xml文件的读取
public class App { ... }
1.4 javaConfig配置DI
先将两个Bean交给spring管理
@Bean
public SomeBean someBean() {
SomeBean someBean = new SomeBean();
return someBean;
}
@Bean
public OtherBean otherBean() {
return new OtherBean();
}
通过方法形参进行注入
//在声明SomeBean的方法形参中直接注入OtherBean对象
@Bean
public SomeBean someBean(OtherBean otherBean) {
SomeBean someBean = new SomeBean();
someBean.setOtherBean(otherBean);
return someBean;
}
调用方法进行注入
@Bean
public OtherBean otherBean(){
return new OtherBean();
}
//调用上面已经声明的otherBean方法
@Bean
public SomeBean someBean() {
SomeBean someBean = new SomeBean();
someBean.setOtherBean(otherBean());
return someBean;
}
1.5 配置类的导入
使用@Import注解导入配置类
传统方式
<!-- mvc.xml中导入applicationContext.xml -->
<import resource="classpath:applicationContext.xml"/>
使用配置类
//主配置类
@Configuration
@Import(OtherConfig.class) //在主配置类中关联分支配置类
public class MainConfig { ... }
//分支配置类
@Configuration
public class OtherConfig { ... }
//测试
@SpringBootTest(classes=MainConfig.class) //加载主配置类
public class App { ... }
@ImportResource注解导入XML配置(了解)
//主配置类
@Configuration
@ImportResource("classpath:applicationContext.xml") //在主配置类中关联XML配置
public class MainConfig { ... }
//测试
@SpringBootTest(classes=MainConfig.class) //加载主配置类
public class App { ... }
1.6 SpringBoot参数配置
我们可以在application.properties进行全局的配置,老代也有用YAML配置的
参数绑定
application.properties配置
#application.properties
jdbc.username=root
jdbc.password=admin
@Value绑定单个属性(方式一)
可以直接在配置类上绑定属性
@Configuration //表示该类是Spring的配置类
public class JavaConfig {
//@Value:从Spring环境对象中根据key读取value
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
@Bean
public MyDataSource myDataSource() {
MyDataSource myDataSource = new MyDataSource();
myDataSource.setUsername(username);
myDataSource.setPassword(password);
return myDataSource;
}
}
也可以在自定义的类上绑定
@Component
@ToString
@Setter
public class MyDataSource {
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
}
@PropertySource注解导入外部属性文件(方式二)
准备db.properties
jdbc.username=root
jdbc.password=admin
配置类方式
使用@PropertySource + @Value
配置类
/**
-
@PropertySource:把属性配置加载到Spring的环境对象中
-
@Value:从Spring环境对象中根据key读取value
*/
@Configuration
@PropertySource(“classpath:db.properties”)
public class JavaConfig {@Value("${jdbc.username}")
private String username;@Value("${jdbc.password}") private String password; @Bean public MyDataSource myDataSource() { MyDataSource myDataSource = new MyDataSource(); myDataSource.setUsername(username); myDataSource.setPassword(password); return myDataSource;
}
}
### 使用Spring的Environment环境对象绑定属性(方式三)
```java
@Configuration
@PropertySource("classpath:db.properties")
public class JavaConfig {
/**
* environment:表示Spring的环境对象,该对象包含了加载的属性数据
* 可以获取到application.properties里面的参数, 也可以获取到@PropertySource中的参数
* 但application.properties的优先级比@PropertySource高
*/
@Autowired
private Environment environment;
@Bean
public MyDataSource myDataSource() {
MyDataSource myDataSource = new MyDataSource();
myDataSource.setUsername(environment.getProperty("jdbc.username"));
myDataSource.setPassword(environment.getProperty("jdbc.password"));
return myDataSource;
}
}
@ConfigurationProperties绑定对象属性(优化)
若觉得上面的方式比较笨重, 可以把前缀抽取到@ConfigurationProperties中, 并且设置类属性与需要绑定的参数名相同, 可实现自动绑定 , 但是如果是使用测试类 , 引用普通的配置类, 则需要在配置类中添加@EnableConfigurationProperties注解
加前缀参数名自动绑定
```java
@Component
@ToString
@Setter
@ConfigurationProperties(“jdbc”) //相当于 @ConfigurationProperties(prefix=“jdbc”)
public class MyDataSource {
private String username;
private String password;
}
```java
@Bean
@ConfigurationProperties("jdbc")
public MyDataSource myDataSource() {
return new MyDataSource();
}
Day02
2.1 自动配置原理
2.1.1 启动类三大注解
启动类:
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
@SpringBootConfiguration:
包含了@Configuration,声明这是一个配置类,如果这个配置类没用声明@ComponentScan(扫描那个包的类作为bean放到该配置类的配置信息中),则默认为该类所在包及其子包!!!!
@SpringBootConfiguration是用来声明当前类是springBoot应用的配置类
因此我们将启动类放在最外层,这样所有的类都会扫描配置到这个配置类里面来,所以不需要我们自行添加配置类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
@EnableAutoConfiguration:
点击注解进去查看,再点击导入的类AutoConfigurationImportSelector(自动配置导入选择器,选择导入 哪一个)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
通过获取候选配置方法–getCandidateConfigurations(),的SpringFactoriesLoader,点进去
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
回去找到所有的META-INF/spring.factories文件,进行加载里面的自动配置对象
public final class SpringFactoriesLoader {
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
private static final Map<ClassLoader, MultiValueMap<String, String>> cache = new ConcurrentReferenceHashMap();
@EnableAutoConfiguration:
主要是通过SpringBoot项目的pom文件的里的基本依赖配置,去猜测我们要配置和使用的对象
所有的自动配置类都来自于我们引入的依赖spring-boot-autoconfigure
但并不是所有的自动配置类都会生效的,需要符合一些条件才可以
2.1.2 查看mvc的自动配置类
我们找到jar包spring-boot-autoconfigure的WebMvcAutoConfig的mvc的自动配置类
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
-
@ConditionalOnWebApplication(type = Type.SERVLET):
ConditionalOn(在web应用下)表示在某个条件下满足项目的类是Type.SERVLET类型即可,而我们当前就是一个web工程满足
-
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class }):
表示在有什么class的条件下即可,当前表示在Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class有的情况下才满足,也就是判断你是否引入了springmvc的依赖,引入则条件满足
-
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class):
表示在在缺失某个bean的情况下满足,也就是说在某个指定的环境下没有这个bean,也就是说如果我们自己配置了 WebMvcConfigurationSupport的Bean的话,条件不满足,失效。如果我们没有配置,则就会帮我们配置下面这个WebMvcConfigurationSupport类(这个自动配置类里面配置了我们需要springMvc) -
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class }):表示最后在进行自动配置,指定的类加载完之后在进行配置
而DispatcherServletAutoConfiguration里又帮我们配置了前端控制器
@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest());
dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest());
dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound());
dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents());
dispatcherServlet.setEnableLoggingRequestDetails(webMvcProperties.isLogRequestDetails());
return dispatcherServlet;
}
现在让我们来看看WebMvcConfigurationSupport类
配置视图解析器
@Bean
@ConditionalOnBean(ViewResolver.class)
@ConditionalOnMissingBean(name = "viewResolver", value = ContentNegotiatingViewResolver.class)
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
resolver.setContentNegotiationManager(beanFactory.getBean(ContentNegotiationManager.class));
// ContentNegotiatingViewResolver uses all the other view resolvers to locate
// a view so it should have a high precedence
resolver.setOrder(Ordered.HIGHEST_PRECEDENCE);
return resolver;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.mvc", name = "locale")
public LocaleResolver localeResolver() {
if (this.mvcProperties.getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) {
return new FixedLocaleResolver(this.mvcProperties.getLocale());
}
AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
return localeResolver;
}
2.2 将原来的ssm改为SpringBoot项目
2.2.1 创建一个SPringBoot初始项目(并且搬移之前的依赖和代码)
引入依赖
<!-- 打包方式jar包 -->
<packaging>jar</packaging>
<!-- 指定父工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
</parent>
<dependencies>
<!-- springboot web包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
启动类
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
添加分页插件的自动配置的依赖(帮我们引入了相关的mybatis的依赖)
不添加普通的分页插件依赖,否则需要进行配置很多
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.13</version>
</dependency>
引入其他依赖
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<!-- huTools-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.4.7</version>
</dependency>
<!--fileupload-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
测试类测试
注意测试类所在的包必须跟启动类所在的包名一致,不然没用启动类的环境,获取不了对应的bean
@SpringBootTest
public class MapperTest {
@Autowired
private DepartmentService departmentService;
@Test
public void testList(){
List<Department> departments = departmentService.selectAll();
System.out.println(departments);
}
}
此时发现找不到mapper相关的bean,因此我们需要对mybatis进行相关的mybatis
2.2.2 集成mybatis
因为自动配置类里配置了mybatis,所以我们需要配置mybatis的自动配置类,而不是普通的配置类,这样才可以使用自动配置mybatis
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis集成到SpringBoot中的依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
配置mapper的扫描路径,不然mapper接口绑定不了xml文件,也就找不到对应的bean
@MapperScan("cn.wolfcode.mapper")
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
配置打印sql信息的日志
#springboot已经帮我们自动配置好Mybatis了,我们只需要引入对应的jar就行
#然后进行对应的属性配置,然后封装成一个对象,最后注入bean中
#默认连接池是Hikari
#如果需要修改,则需要引入对应的mybatis的自动配置包
#如果只是引入普通的引入mybatis包的话,还需要在properties文件进行配置告诉是什么连接池对象(和普通的xml使用相同)
#mybatis.configuration.lazy-loading-enabled=true
#mybatis.configuration.lazy-load-trigger-methods=clone
#mybatis.mapper-locations=classpath:cn/wolfcode/crm/mapper/*Mapper.xml
#mybatis.type-aliases-package=cn.wolfcode.crm.domain
#打印SQL日志
logging.level.cn.wolfcode.mapper=trace
因为我们配置的是在日志中显示(在右边)
我们可以通过把配置使其左边显示sql
#showSQL
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
2.2.3 配置数据库连接池
#配置数据库连接池
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql:///ssm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=admin
其实 , 在springboot2.0之后 , 采用的默认连接池就是Hikari, 号称"史上最快的连接池", 所以我们没有添加依赖也能直接用, springboot的自动配置中含有DataSourceAutoConfiguration配置类, 会先检查容器中是否已经有连接池对象, 没有则会使用默认的连接池, 并根据特定的属性来自动配置连接池对象, 用到的属性值来源于DataSourceProperties对象
集成Druid集成
我们添加的是druid的自动配置类,这样会帮我们创建druid的连接池对象,DataSourceAutoConfiguration发现我们有了自己的连接池对象,则不会帮我们配置默认的Hikari,不满足条件
<!-- druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.21</version>
</dependency>
如果我们使用普通的druid配置的话会麻烦很多
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.19</version>
</dependency>
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
2.2.4 事务配置
导入依赖
<!-- 支持使用 Spring AOP 和 AspectJ 进行切面编程。 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
使用xml方式(了解即可)
采取配置类和XML混用的策略, 在配置类上使用@ImportResource(“classpath:spring-tx.xml”)
注解方式
直接在业务层实现类上或者其方法上直接贴@Transactional注解即可
#SpringBoot默认优先选择CGLIB代理,如果需要改为优先使用JDK代理,需要做以下配置
#spring.aop.proxy-target-class=false #优先使用JDK代理
SpringBoot 自动配置中提供了TransactionAutoConfiguration事务注解自动配置类 , 引入了事务的依赖后, 可直接使用@Transactional注解
在测试类上添加方法, 在service层可插入运行时异常的代码进行测试
@Test
public void testSave(){
Department department = new Department();
department.setName("测试");
departmentService.save(department);
}
2.2.5 web集成
添加依赖
<!-- springboot web启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
修改端口
server.port=80
在springBoot中默认帮我们自动配置了resource文件下的static放的是静态资源,template放的是模板文件
而且在这两个文件也只是用来放置文件,不参数浏览器地址,也就是不会被视图解析器解析为对应的路径
相当于以前webapp的根目录下放置对应的文件夹和文件
静态资源处理
- 默认情况下,Springboot会从classpath下的 /static , /public , /resources , /META-INF/resources下加载静态资源
- 可以在application.properties中配置spring.resources.staticLocations属性来修改静态资源加载地址
- 因为应用是打成jar包,所以之前的src/main/webapp就作废了,如果有文件上传,那么就的必须去配置图片所在的路径
路径映射配置(了解)
在springboot自动配置中, WebMvcAutoConfiguration自动配置类导入了DispatcherServletAutoConfiguration配置对象 , 会自动创建DispatcherServlet前端控制器 , 默认的< url-pattern >是 / , **SpringBoot多数用于前后端分离和微服务开发,默认支持RESTFul规范,所以一般都是使用默认匹配 / ,不做改动 **
#在匹配模式时是否使用后缀模式匹配
spring.mvc.pathmatch.use-suffix-pattern=true
集成Freemarker
原来我们在ssm中的xml要导入普通的freemarker依赖,要配置FreeMarkerConfigurer和FreeMarkerViewResolve两个对象到容器中,十分麻烦。
而springBoot里帮我们自动配置了freemarker,我们只需要引入依赖即可满足条件创建对应的对象
<!-- SpringBoot集成FreeMarker的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
集成原理
SpringBoot的自动配置中含有FreeMarkerAutoConfiguration配置对象,该配置对象又导入了FreeMarkerReactiveWebConfiguration配置对象,在里面创建了FreeMarkerConfigurer和FreeMarkerViewResolve两个对象交给Spring管理,并且设置了默认的属性值,这些属性值来源于FreeMarkerProperties对象
常见属性配置
spring.freemarker.enabled=true: 是否开启freemarker支持
spring.freemarker.charset=UTF-8: 模板编码
spring.freemarker.content-type=text/html: 模板contenttype
spring.freemarker.expose-session-attributes: 是否开启session属性暴露,默认false
spring.freemarker.prefix: 加载模板时候的前缀
spring.freemarker.settings.*: 直接配置freemarker参数
spring.freemarker.suffix: 模板文件后缀
spring.freemarker.template-loader-path=classpath:/templates/: 模板加载地址
#一般我们会做3个配置,其余默认即可
#暴露session对象的属性
spring.freemarker.expose-session-attributes=true
#配置为传统模式,空值自动处理
spring.freemarker.settings.classic_compatible=true
#重新指定模板文件后缀 springboot 2.2.x 后 默认后缀为 .ftlh
spring.freemarker.suffix=.ftl
2.2.6 统一异常处理
框架自带方式
SpringBoot默认情况下,会把所有错误都交给BasicErrorController类完成处理,错误的视图导向到 classpath:/static/error/ 和 classpath:/templates/error/ 路径上,http状态码就是默认视图的名称
如: 出现404错误 -> classpath:/static/error/404.html 或者 出现5xx类错误 -> classpath:/static/error/5xx.html
控制器增强器方式
自己定义一个控制器增强器,专门用于统一异常处理,该方式一般用于5xx类错误
@ControllerAdvice //控制器增强器
public class ExceptionControllerAdvice {
@ExceptionHandler(RuntimeException.class) //处理什么类型的异常
public String handlException(RuntimeException e, Model model) {
return "errorView"; //错误页面视图名称
}
}
2.2.7 添加拦截器
在传统的XML方式中,我们需要在< mvc:interceptors >标签中去注册我们自定义的拦截器,在SpringBoot中,
提供了WebMvcConfigurer配置接口 , 是使用JavaConfig配置SpringMVC的标准,如果我们需要对SpringMVC做配置,则需要让我们的配置类实现该接口 , 若是需要注册拦截器, 则实现接口中的addInterceptors方法即可
@Configuration
public class WebConfigurer implements WebMvcConfigurer {
public static final String[] excludePathPatterns = {"/css/**","/img/**",
"/js/**", "/login.html",
"/UserLogin", "/index", "/indexMessage", "/appointment/selectByBussiness", "/appointment/selectBySn",
"/appointment/save", "/messageBoard/indexMessage", "/messageBoard/massageItem",
"/messageBoard/saveOrUpdate", "/systemDictionaryItem/selectByParentId", "/d/list",
"/d/delete"
};
@Autowired
private LoginIntercepter loginIntercepter;
// @Autowired
// private PermissionIntercepter permissionIntercepter;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginIntercepter).addPathPatterns("/**").excludePathPatterns(excludePathPatterns);
// registry.addInterceptor(permissionIntercepter).addPathPatterns("/**").excludePathPatterns(excludePathPatterns).excludePathPatterns("/login.html");
}
}
2.2.8 日志的使用
类中使用日志输出
在我们自定义的类中如果要使用日志框架来输出
方式1: 在类中定义一个静态Logger对象
这里传入当前类的作用是方便输出日志时可以清晰地看到该日志信息是属于哪个类的
private static final Logger log = LoggerFactory.getLogger(当前类.class);
方式2: 使用lombok提供的@Slf4j注解来简化代码 , 其实和方式1的作用是一样的
@Slf4j
@Service
public class PermissionServiceImpl implements IPermissionService {}
在需要输出日志的地方使用日志的输出方法
log.info(...);
log.error(...);
...
//输出日志中有变量可以使用{}作为占位符
log.info("删除id为{}的数据", id);
如果要修改日志级别,最快速的方式是在application.properties配置
#把日志级别修改为debug,不过我们一般不会更改,除非要调试找bug,不然控制台显示的内容太多也容易乱
logging.level.root=debug
Logback配置文件的使用
Logback框架默认会自动加载classpath:logback.xml,作为框架的配置文件,在SpringBoot中使用时,还会额外的支持自动加载classpath:logback-spring.xml,在SpringBoot中推荐使用logback-spring.xml,功能更强大些
<?xml version="1.0" encoding="UTF-8"?> ${appName} <!-- appender:日志输出对象,配置不同的类拥有不同的功能
ch.qos.logback.core.ConsoleAppender:日志输出到控制台
-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd-HH:mm:ss} %level [%thread]-%logger{35} >> %msg %n</pattern>
</encoder>
</appender>
<!-- ch.qos.logback.core.FileAppender:日志输出到文件中
<appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
<encoder>
<pattern>%-4relative [%thread] %level %logger{35} - %msg %n</pattern>
</encoder>
<append>true</append>
<file>mylog.log</file>
</appender>
-->
<!-- root是项目通用的logger,一般情况下都是使用root配置的日志输出
level:按照级别输出日志,日志级别,级别越高,输出的内容越少
trace < debug < info < warn < error
-->
<root level="info">
<appender-ref ref="STDOUT" />
</root>
<!-- 自定义的logger,用于专门输出特定包中打印的日志
<logger name="cn.wolfcode.crm.mapper" level="trace">
</logger>
-->
</configuration>
2.3 其他功能
2.3.1 修改banner
将对应的banner.txt放入到resource即可生效
2.3.2 使用热部署
导入依赖
<!-- SpringBoot热部署插件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
SpringBoot重启是reload重启,通过监控classpath的变化,如果classpath中的文件发生变化,即触发重启.springboot通过两个classpath来完成reload,一个basic classloader中加载不变的类(jar包中的类),一个restart classloader中加载classpath中的类(自己写的类),重启的时候,restart classloader中的类丢弃并重新加载
#默认排除的资源
spring.devtools.restart.exclude=static/**,templates/**,public/**
#增加额外的排除资源
spring.devtools.restart.additional-exclude=public/** #处理默认配置排除之外的
spring.devtools.restart.enabled=false #禁用自动重启
2.3.3 切换运行环境(了解)
在实际开发中我们需要不同的环境
我们需要为不同的环境创建不同的配置文件,不同的环境中系统的参数配置是不同的如:连接开发数据和测试数据库的URL绝对是不同的,那么怎么快速的切换系统运行的环境?
application-dev.properties
server.port=8081
application-test.properties
server.port=8082
在application.properties中指定需要使用的环境即可
#指定使用的环境是dev
spring.profiles.active=dev