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: test
WEB开发
静态资源
1.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>
SpringMVC扩展
编写一个配置类实现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页面,发生错误即可自动跳转到这个页面。
整合druid数据源
导包
<!-- 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=500
type属性即是指定数据源的
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过滤器来过滤掉不需要监控的路径。