1.修改springboot启动banner
到网上搜一个ascii艺术字并复制,然后新建banner.txt把艺术字粘贴到文件中
重启后即生效
2.springboot自动配置原理
继承:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent>在pom.xml中定义了继承结构,当前应用继承自spring-boot-starter-parent,spring-boot-starter-parent继承自spring-boot-dependencies,在spring-boot-dependencies中管理着核心依赖和版本,这也是我们在pom.xml无需写版本号的原因,不写会继承自父artifact定义的版本号。
启动器:
springboot帮助我们将某个场景下需要使用到的依赖和配置打包成一个启动器,我们需要使用某个场景的功能直接导入这个启动器依赖就可以了。加入我们需要使用到web,那么导入下面的依赖就完成了相关依赖的导入,
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>应用入口:
3.yaml语法
# 字符串 name: 左西俊 # 对象 student1: name: 王芳 age : 23 student2: {name: 王芳,age: 23} #数组 students1: - s1 - s2 - s3 students2: [s1,s2,s3]4.配置文件属性绑定
首先导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>编写配置文件:
person: name: zuoxijun age: 23 happy: false birth: 1996/6/19 maps: k1: 2 k2: 3 lists: - 1 - 2 - 3 dog: name: wangzai age: 3编写实体类,使用@Component注解将类交给spring管理,使用@ConfigurationProperties注解将配置文件属性和实体类属性进行按名映射:
@Component @ConfigurationProperties(prefix = "person") public class Person { private String name; private Integer age; private Boolean happy; private Date birth; private Map<String, Integer> maps; private List<Integer> lists; private Dog dog; ........ }@Component注解加在类上,标明该类由spring进行管理
属性注入还可以通过@Value注解进行单独注入,@Value由两种语法#{}和${},@Value和@ConfigurationProperties的区别如下:
松散绑定也即配置文件中的last-name可以对应到java bean中的lastName
EL表达式:
//整形 @Value("#{11}") //字符串 @Value("#{'haha'}") //其它bean的属性 @Value("#{bean.name}")取出properties文件中的属性:
通过@PropertySource绑定properties文件,通过@Component将类将给spring管理,通过${}取出properties文件属性
@Component @PropertySource("classpath:my.properties") public class Dog { @Value("${test.name}") private String name; @Value("${test.age}") private Integer age; ......... }5.@Bean注解
一般和@Configuration注解一起使用
@Configuration public class MyConfiguration { @Bean(name = {"ddd", "ccc"}) public Dog dog1(){ return new Dog("发财", 23); } }不指定name属性时,spring会使用方法名+首字母小写作为该bean的名字,指定name后使用name属性的值作为该bean的名字,name可以指定多个名字。
bean的默认作用域为singleton,如果想修改可以结合@Scope注解
6.@Autowired和@Resource
可以加载属性或者set方法上,@Autowired默认是按照类型进行装配的,如果存在多个相同类型的bean就会报错,它会尝试使用属性名作为bean的名称去搜索,如果不能唯一找到一个bean则抛出异常。可以和@Qualifier组合使用,定位一个指定名称的bean。@Autowired是spring为我们定义的注解。
@Resource是javax包下的不属于spring,它可以加在属性或者set方法上,默认按照byName进行装配,如果byName装配失败则按照byType进行装配。注意如果指定了它的type属性则一定按照byType进行装配,如果指定了它的name属性则一定按照byName进行装配。
7.JSR303校验
导入依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>@Validated在bean上开启检验:
@Component @PropertySource("classpath:my.properties") @Validated public class Dog { .............. }在需要校验的属性上添加校验注解(如校验是否是email):
@Component @PropertySource("classpath:my.properties") @Validated public class Dog { @Email @Value("${test.name}") private String name; ................ }所有的校验注解类型如下图:
8.springboot多环境配置
spring: profiles: active: test --- server: port: 8081 spring: profiles: dev --- server: port: 8083 spring: profiles: test1.webjars
通过maven导入jar包来使用静态资源,以导入jquery为例
<dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.5.1</version> </dependency>在WebMvcAutoConfiguration中:
if (!registry.hasMappingForPattern("/webjars/**")) { this.customizeResourceHandlerRegistration( registry.addResourceHandler(new String[]{"/webjars/**"}) .addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}) .setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl)); }将/webjars/**请求映射到/META/resources/webjars/目录下,而我们通过maven导入的jar包符合这个结构:
所以我们通过访问http://ip:8080/webjars/jquery/3.5.1/jquery.js能访问到静态资源
2.静态资源目录
String staticPathPattern = this.mvcProperties.getStaticPathPattern(); if (!registry.hasMappingForPattern(staticPathPattern)) { this.customizeResourceHandlerRegistration(registry .addResourceHandler(new String[]{staticPathPattern}) .addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())) .setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl)); }staticPathPattern资源访问路径模式,是从WeMvcProperties中获得的:
public WebMvcProperties() { this.localeResolver = WebMvcProperties.LocaleResolver.ACCEPT_HEADER; this.format = new WebMvcProperties.Format(); this.dispatchTraceRequest = false; this.dispatchOptionsRequest = true; this.ignoreDefaultModelOnRedirect = true; this.publishRequestHandledEvents = true; this.throwExceptionIfNoHandlerFound = false; this.logResolvedException = false; this.staticPathPattern = "/**"; this.async = new WebMvcProperties.Async(); this.servlet = new WebMvcProperties.Servlet(); this.view = new WebMvcProperties.View(); this.contentnegotiation = new WebMvcProperties.Contentnegotiation(); this.pathmatch = new WebMvcProperties.Pathmatch(); }而在WebMvcProperties中它的值为/**,可以通过在yaml文件中配置修改这个路径
this.resourceProperties.getStaticLocations(),resourceProperties是ResourceProperties的实例,staticLocations的值如下:
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{ "classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/" };即访问/**会映射到上面四个类路径下的文件夹下,优先级依次是META-INF/resources > resources > static > public
因此可以通过http://ip/文件名,访问这四个文件夹下的静态资源。
修改staticPathPattern和staticLocations的yaml配置对应为:
spring: mvc: static-path-pattern: yourPattern resources: static-locations: yourLocaltions(数组类型)从上面可以看出,springboot的核心就是***Autoconfiguration,***Properties类,AutoConfiguration持有Properties的引用,Properties类绑定了yaml配置文件的某个前缀,三者共同协调实现springboot的自动配置。
直接访问ip地址,如httlp://localhost:8080/会默认展示一个页面,即index首页页面,在WebMvcAutoConfiguration类中可以发现下面的代码:
private Optional<Resource> getWelcomePage() { String[] locations = WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations()); return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst(); } private Resource getIndexHtml(String location) { return this.resourceLoader.getResource(location + "index.html"); }springboot的首页默认是从静态资源目录,即{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"}下面找index.html文件,这个html即为首页。
另外我们也可以通过定义Controller来映射index.html文件,首先在templates文件夹下新建index.html文件,然后新建IndexController来映射:
@Controller public class IndexController { @RequestMapping("/") public String index(){ return "index"; } }注意这种方式要添加thymeleaf引擎来解析视图:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
编写一个配置类实现WebMvcConfigurer接口,类上添加@Configugration注解,之后实现不同的方法来扩展springmvc的功能,如扩展一个视图控制器,如下所示:
@Configuration public class MyMvcConfiguration implements WebMvcConfigurer { //springmvc扩展 添加视图控制器 @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/zuoxijun").setViewName("test1"); } }1.将idea的文件编码全部修改为utf-8
2.创建properties语言包文件
3.再application.yaml中配置语言包的basename
4.自定义locale处理器,接收不同的url参数对应到不同的locale
public class MyLocaleResolver implements LocaleResolver { private static Set<String> supportLanguages = new HashSet<>(); static { supportLanguages.add("en_US"); supportLanguages.add("zh_CN"); } @Override public Locale resolveLocale(HttpServletRequest httpServletRequest) { String lang = httpServletRequest.getParameter("l"); System.out.println(lang); if(supportLanguages.contains(lang)){ String[] s = lang.split("_"); return new Locale(s[0], s[1]); } return Locale.getDefault(); } }5.将locale处理器交给spring管理
注意这里的LocaleResolver的bean的id必须是localeResolver,所以方法名必须是localeResolver,否则是不生效的,springboot不会用我们自定义的LocaleResolver.这是因为在WebMvcAutoConfiguration中:
@ConditionalOnMissingBean判断id为localResolver的bean不存在就会使用自动配置的LocaleResolver.
6.前端添加链接
1.创建拦截器,实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//判断是否登录 if(Boolean.TRUE.equals(request.getSession().getAttribute("login"))){ return true; } request.setAttribute("notLogin", "notLogin"); request.getRequestDispatcher("/index").forward(request, response); return false; } }2.注册拦截器
在templates下创建error目录,下面放上响应错误的html页面,发生错误即可自动跳转到这个页面。
导包
<!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.21</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>切换druid数据源,默认是Hikari数据源
datasource: url: jdbc:mysql://106.14.205.174/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC username: root password: 190539 driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource #Spring Boot 默认是不注入这些属性值的,需要自己绑定 #druid 数据源专有配置 initialSize: 5 minIdle: 5 maxActive: 20 maxWait: 60000 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: SELECT 1 FROM DUAL testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: true #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入 #如果允许时报错 java.lang.ClassNotFoundException: org.apache.log4j.Priority #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j filters: stat,wall,log4j maxPoolPreparedStatementPerConnectionSize: 20 useGlobalDataSourceStat: true connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500type属性即是指定数据源的
druid自定义配置:
@Configuration public class DruidConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource druidDataSource(){ return new DruidDataSource(); } //注册 @Bean //注册servlet来跳转到后台监控页面 public ServletRegistrationBean bb(){ ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); Map<String, String> initParams = new HashMap<>(); initParams.put("allow", ""); initParams.put("loginUsername", "admin"); initParams.put("loginPassword", "190539"); servletRegistrationBean.setInitParameters(initParams); return servletRegistrationBean; } //过滤一下不需要druid进行监控的页面 @Bean public FilterRegistrationBean aa(){ FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter()); Map<String, String> map = new HashMap<>(); map.put("exclusions","/druid/*,/jdbc/*, /druid"); filterRegistrationBean.setInitParameters(map); return filterRegistrationBean; } }druid内置了一个servlet提供浏览器监控展示服务即StatViewServlet。,用ServletRegistrationBean来注册这个Servlet,
对于不想进行统计的页面,可以通过FilterRegistrationBean注册WebStatFilter过滤器来过滤掉不需要监控的路径。