springboot学习笔记

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过滤器来过滤掉不需要监控的路径。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值