SpringBoot

一、自定义属性配置

  1. 通过@Value注解读取(配置项比较少的时候)

    developer.name=wangxiangqian
    
    @Controller
    public class IndexController {
    
        @Value("${developer.name}")
        private String user;
    
        @RequestMapping(value = "/say")
        public @ResponseBody String say(){
    		return user;
    	}
    }
    
  2. 通过映射类读取(配置项目比较多的时候)

    
    school.name=xiwangxiaoxue
    
    school.webist=www.wangxiangqian.com
    
    @Component
    @ConfigurationProperties(prefix = "school")
    public class School {
    
    
        private String name;
    
    
        private String webist;
    
    
        public School() {
        }
    
    
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getWebist() {
            return webist;
        }
    
        public void setWebist(String webist) {
            this.webist = webist;
        }
    
    
    }
    
    @Controller
    public class IndexController {
    
        @Autowired
        private School school;
    
        @RequestMapping(value = "/say")
        public @ResponseBody String say(){
    		return school.getName()+"----------"+school.getWebist();
    
        }
    }
    
  3. 通过Environment对象读取(spring ioc 直接就给我们创建了该对象)

    @Autowired
    Environment env;
    
    @GetMapping("/user")
    Public String user() {
            StringBuilder sb = new StringBuilder();
            sb.append("从Environment中获取配置:\n");
            sb.append(env.getProperty("myconfig.user.name"));//注意这里不加${}
            return sb.toString();
    }
    
    
  4. 通过嵌套静态内部类读取(参考server.前缀的方式)

二、集成JSP

  1. 添加依赖

    <!--引入SpringBoot内嵌Tomcat对jsp的解析依赖,不添加解析不了jsp-->
            <!--仅仅只是展示jsp页面,只添加以下一个依赖-->
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-jasper</artifactId>
            </dependency>
    
    
  2. 指定编译路径

    <!--
                Springboot项目默认推荐使用的前端引擎是thymeleaf
                现在我们要使用springboot集成jsp,手动指定jsp最后编译的路径
                而且springboot集成jsp编译jsp的路径是springboot规定好的位置
                META-INF/resources
            -->
            <resources>
                <resource>
                    <!--源文夹-->
                    <directory>src/main/webapp</directory>
                    <!--指定编译到META-INF/resources-->
                    <targetPath>META-INF/resources</targetPath>
                    <!--指定源文件夹中的哪个资源要编译进行-->
                    <includes>
                        <include>*.*</include>
                    </includes>
                </resource>
            </resources>
    
  3. 配置视图解析器

    spring.mvc.view.prefix=/
    spring.mvc.view.suffix=.jsp
    

三、集成Mybatis

  1. 添加依赖

    <!--MySQL驱动-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <!--<version>5.1.9</version>-->
            </dependency>
    
            <!--MyBatis整合SpringBoot框架的起步依赖-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.0.0</version>
            </dependency>
    
  2. mybatis逆向工程

    1. 添加插件

      <!--mybatis 代码自动生成插件-->
                  <plugin>
                      <groupId>org.mybatis.generator</groupId>
                      <artifactId>mybatis-generator-maven-plugin</artifactId>
                      <version>1.3.6</version>
                      <configuration>
                          <!--配置文件的位置-->
                          <configurationFile>GeneratorMapper.xml</configurationFile>
                          <verbose>true</verbose>
                          <overwrite>true</overwrite>
                      </configuration>
                  </plugin>
      
    2. 逆向工程文件

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE generatorConfiguration
              PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
              "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
      <generatorConfiguration>
          <!-- 指定连接数据库的 JDBC 驱动包所在位置,指定到你本机的完整路径 -->
          <classPathEntry location="D:\mysql-connector-java-5.1.38.jar"/>
          <!-- 配置 table 表信息内容体,targetRuntime 指定采用 MyBatis3 的版本 -->
          <context id="tables" targetRuntime="MyBatis3">
              <!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 -->
              <commentGenerator>
                  <property name="suppressAllComments" value="true"/>
              </commentGenerator>
              <!-- 配置数据库连接信息 -->
              <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                              connectionURL="jdbc:mysql://192.168.154.128:3306/springboot"
                              userId="root"
                              password="123">
              </jdbcConnection>
              <!-- 生成 model 类,targetPackage 指定 model 类的包名, targetProject 指定
              生成的 model 放在 eclipse 的哪个工程下面-->
              <javaModelGenerator targetPackage="com.bjpowernode.springboot.model"
                                  targetProject="src/main/java">
                  <property name="enableSubPackages" value="false"/>
                  <property name="trimStrings" value="false"/>
              </javaModelGenerator>
              <!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的
              包名, targetProject 指定生成的 mapper.xml 放在 eclipse 的哪个工程下面 -->
              <sqlMapGenerator targetPackage="com.bjpowernode.springboot.mapper"
                               targetProject="src/main/java">
                  <property name="enableSubPackages" value="false"/>
              </sqlMapGenerator>
              <!-- 生成 MyBatis 的 Mapper 接口类文件,targetPackage 指定 Mapper 接口类的包
              名, targetProject 指定生成的 Mapper 接口放在 eclipse 的哪个工程下面 -->
              <javaClientGenerator type="XMLMAPPER"
                                   targetPackage="com.bjpowernode.springboot.mapper" targetProject="src/main/java">
                  <property name="enableSubPackages" value="false"/>
              </javaClientGenerator>
      
              <!-- 数据库表名及对应的 Java 模型类名 -->
              <table tableName="t_student" domainObjectName="Student"
                     enableCountByExample="false"
                     enableUpdateByExample="false"
                     enableDeleteByExample="false"
                     enableSelectByExample="false"
                     selectByExampleQueryId="false"/>
          </context>
      </generatorConfiguration>
      
    3. 点击编译插件generator

  3. 手动指定资源文件夹

     <!--手动指定文件夹为resources-->
            <resources>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml</include>
                    </includes>
                </resource>
            </resources>
    
  4. 添加注解,将mapper对象放到容器中(两种方式)

    @Mapper //扫描DAO接口到spring容器
    public interface StudentMapper {
        int deleteByPrimaryKey(Integer id);
    
        int insert(Student record);
    
        int insertSelective(Student record);
    
        Student selectByPrimaryKey(Integer id);
    
        int updateByPrimaryKeySelective(Student record);
    
        int updateByPrimaryKey(Student record);
    }
    
    @SpringBootApplication  //开启spring配置
    @MapperScan("com.bjpowernode.springboot.mapper") //开启扫描Mapper接口的包以及子目录
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }
    
  5. 设置连接数据库的信息

    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://192.168.154.128:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
    spring.datasource.username=root
    spring.datasource.password=123
    
  6. 指定mybatis映射文件的路径(将mapper文件放到resources中)

    mybatis.mapper-locations=classpath:mapper/*.xml
    

四、事务@Transactional

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Transactional
    @Override
    public int updateStudentById(Student student) {

        //修改成功
        int i = studentMapper.updateByPrimaryKeySelective(student);

        //失败
        int a = 10/0;

        return i;
    }
}

五、集成SpringMVC常用注解

  1. @RestController

    //该方法请求方式支持:GET和POST请求
        @RequestMapping(value = "/queryStudentById",method = {RequestMethod.GET,RequestMethod.POST})
        public Object queryStudentById(Integer id) {
            Student student = new Student();
            student.setId(id);
            return student;
        }
    
    
    //    @RequestMapping(value = "/queryStudentById2",method = RequestMethod.GET)
        @GetMapping(value = "/queryStudentById2") //相当于上一句话,只接收GET请求,如果请求方式不对会报405错误
        //该注解通过在查询数据的时候使用 -> 查询
        public Object queryStudentById2() {
            return "Ony GET Method";
        }
    
    //    @RequestMapping(value = "/insert",method = RequestMethod.POST)
        @PostMapping(value = "/insert") //相当于一句话
        //该注解通常在新增数据的时候使用 -> 新增
        public Object insert() {
            return "Insert success";
        }
    
    //    @RequestMapping(value = "/delete",method = RequestMethod.DELETE)
        @DeleteMapping(value = "/delete")//相当于上一句话
        //该注解通常在删除数据的时候使用 -> 删除
        public Object delete() {
            return "delete Student";
        }
    
    
    //    @RequestMapping(value = "/update",method = RequestMethod.PUT)
        @PutMapping(value = "/update") //相当于上一句话
        //该注解通常在修改数据的时候使用 -> 更新
        public Object update() {
            return "update student info1";
        }
    

六、RESTful风格

//    @RequestMapping(value = "/student/detail/{id}/{age}")
    @GetMapping(value = "/student/detail/{id}/{age}")
    public Object student1(@PathVariable("id") Integer id,
                           @PathVariable("age") Integer age) {
        Map<String,Object> retMap = new HashMap<>();

        retMap.put("id",id);
        retMap.put("age",age);
        return retMap;
    }

//    @RequestMapping(value = "/student/detail/{id}/{status}")
    @GetMapping(value = "/student/detail/{id}/{status}")
    public Object student2(@PathVariable("id") Integer id,
                           @PathVariable("status") Integer status) {
        Map<String,Object> retMap = new HashMap<>();

        retMap.put("id",id);
        retMap.put("status",status);
        return retMap;
    }

    //以上代码student1和student2会出现请求路径冲突问题(可以通过请求方式区分)
    //通常在RESTful风格中方法的请求方式会按增删改查的请求方式来区分
    //修改请求路径
    //RESUful请求风格要求路径中使用的单词都是名称,最好不要出现动词

    @DeleteMapping(value = "/student/{id}/detail/{city}")
    public Object student3(@PathVariable("id") Integer id,
                           @PathVariable("city") Integer city) {
        Map<String,Object> retMap = new HashMap<>();

        retMap.put("id",id);
        retMap.put("city",city);
        return retMap;
    }

七、集成Redis

  1. 添加依赖

    <!--SpringBoot集成Redis的起步依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    
  2. 在核心配置文件添加redis的配置

    spring.redis.host=192.168.154.128
    spring.redis.port=6379
    spring.redis.password=123456
    
  3. 依赖提供的redis模板对象

    @Service
    public class StudentServiceImpl implements StudentService {
    
        @Autowired
        private RedisTemplate<Object,Object> redisTemplate;
    
        @Override
        public void put(String key, String value) {
    
            redisTemplate.opsForValue().set(key,value);
    
        }
    
        @Override
        public String get(String key) {
    
            String count = (String) redisTemplate.opsForValue().get(key);
    
            return count;
        }
    }
    
    

八、集成dubbo

  1. 服务提供者

    <!--Dubbo集成SpringBoot起步依赖-->
            <dependency>
                <groupId>com.alibaba.spring.boot</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>2.0.0</version>
            </dependency>
    
            <!--注册中心-->
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>0.10</version>
            </dependency>
    
    		<!--接口工程-->
            <dependency>
                <groupId>com.bjpowernode.springboot</groupId>
                <artifactId>023-springboot-dubbo-ssm-interface</artifactId>
                <version>1.0.0</version>
            </dependency>
    
    
    #内嵌端口号
    server.port=8081
    #上下文根
    server.servlet.context-path=/
    
    #dubbo的配置
    spring.application.name=024-springboot-dubbo-ssm-provider
    #当前工程是一个服务提供者
    spring.dubbo.server=true
    #设置注册中心
    spring.dubbo.registry=zookeeper://192.168.154.128:2181
    
    @Component
    @Service(interfaceName = "com.bjpowernode.springboot.service.StudentService",version = "1.0.0",timeout = 15000)
    public class StudentServiceImpl implements StudentService {}
    
  2. 服务消费者

    	<!--Dubbo集成SpringBoot起步依赖-->
    	        <dependency>
    	            <groupId>com.alibaba.spring.boot</groupId>
    	            <artifactId>dubbo-spring-boot-starter</artifactId>
    	            <version>2.0.0</version>
    	        </dependency>
    	
    	        <!--注册中心-->
    	        <dependency>
    	            <groupId>com.101tec</groupId>
    	            <artifactId>zkclient</artifactId>
    	            <version>0.10</version>
    	        </dependency>
    
    			<!--接口工程-->
    	        <dependency>
    	            <groupId>com.bjpowernode.springboot</groupId>
    	            <artifactId>023-springboot-dubbo-ssm-interface</artifactId>
    	            <version>1.0.0</version>
    	        </dependency>
    	
    
     	```yaml
     	#内嵌端口号
     	server.port=8081
     	#上下文根
     	server.servlet.context-path=/				
     	
     	#dubbo的配置
     	spring.application.name=022-springboot-dubbo-ssm-consumer
     	#设置注册中心
     	spring.dubbo.registry=zookeeper://192.168.154.128:2181
     	```
    
    @Reference(interfaceName = "com.bjpowernode.springboot.service.StudentService",version = "1.0.0",check = false)
        private StudentService studentService;
    
  3. 开启dubbo注解配置

    @SpringBootApplication
    @EnableDubboConfiguration   //开启dubbo配置
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }
    

九、springboot java工程

  1. 直接获取ConfigurableApplication()
    @SpringBootApplication
    public class Application {
    
    
        public static void main(String[] args) {
            /**
             * Springboot程序启动后,返回值是ConfigurableApplicationContext,它也是一个Spring容器
             * 它其实相当于原来Spring容器中启动容器ClasspathXmlApplicationContext
             */
    
            SpringApplication.run(Application.class, args);
    
            //获取Springboot容器
            ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);
    
            //从spring容器中获取指定bean对象
            StudentService studentService = (StudentService) applicationContext.getBean("studentServiceImpl");
    
            //调用业务方法
            String sayHello = studentService.sayHello();
    
            System.out.println(sayHello);
    
        }
    
  2. 实现CommandLineRuner,重写run方法
    @SpringBootApplication  //开启spring配置
    public class Application implements CommandLineRunner {
    
        @Autowired
        private StudentService studentService;
    
        public static void main(String[] args) {
            //SpringBoot启动程序,会初始化Spring容器
            SpringApplication.run(Application.class, args);
        }
    
    
        //重写CommandLineRunner类中的run方法
        @Override
        public void run(String... args) throws Exception {
    
            //调用业务方法
            String sayHello = studentService.sayHello("World");
    
            System.out.println(sayHello);
        }
    }
    

十、关闭和修改LOGO

  1. 关闭logo

    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
    
    //        SpringApplication.run(Application.class,args);
    
            //获取入口SpringBoot类
            SpringApplication springApplication = new SpringApplication(Application.class);
    
            //设置它的属性
            springApplication.setBannerMode(Banner.Mode.OFF);
    
            springApplication.run(args);
    
        }
    
    }
    
  2. 修改logo
    在 src/main/resources 放入 banner.txt 文件,该文件名字不能随意,文件中的内容就是要输出的 logo ;可以利用网站生成图标:https://www.bootschool.net/ascii 或 者
    http://patorjk.com/software/taag/,将生成好的图标文字粘贴到 banner.txt 文件中,然后将关闭 logo 输出的语句注释,启动看效果

十一、拦截器

  1. 定义拦截器类

    public class UserInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
            System.out.println("进入拦截器------------------------------");
            //编写业务拦截的规则
            //从session中获取用户的信息
            User user = (User) request.getSession().getAttribute("user");
    
            //判断用户是否登录
            if (null == user) {
                //未登录
                response.sendRedirect(request.getContextPath() + "/user/error");
                return false;
            }
    
    
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
        }
    }
    
  2. 定义配置类

    @Configuration  //定义此类为配置文件(即相当于之前的xml配置文件)
    public class InterceptorConfig implements WebMvcConfigurer {
    
        //mvc:interceptors
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
    
            //要拦截user下的所有访问请求,必须用户登录后才可访问,
            // 但是这样拦截的路径中有一些是不需要用户登录也可访问的
            String[] addPathPatterns = {
                "/user/**"
            };
    
            //要排除的路径,排除的路径说明不需要用户登录也可访问
            String[] excludePathPatterns = {
                "/user/out", "/user/error","/user/login"
            };
    
            //mvc:interceptor bean class=""
            registry.addInterceptor(new UserInterceptor()).addPathPatterns(addPathPatterns).excludePathPatterns(excludePathPatterns);
        }
    }
    

十二、使用servlet

  1. 第一种方式(注解方式)

    @WebServlet(urlPatterns = "/myservlet")
    public class MyServlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           resp.getWriter().println("My SpringBoot Servlet-1");
           resp.getWriter().flush();
           resp.getWriter().close();
    
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
    
    @SpringBootApplication  //开启spring配置
    @ServletComponentScan(basePackages = "com.bjpowernode.springboot.servlet")
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }
    
    
  2. 第二种方式(通过配置类注册组件)

    public class MyServlet extends HttpServlet {
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            resp.getWriter().println("My SpringBoot Servlet-2");
            resp.getWriter().flush();
            resp.getWriter().close();
        }
    
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            doGet(req, resp);
        }
    }
    
    
    @Configuration  //该注解将此类定义为配置类(相当一个xml配置文件)
    public class ServletConfig {
    
        //@Bean是一个方法级别上的注解,主要用在配置类里
        //相当于一个
        // <beans>
        //      <bean id="" class="">
        // </beans>
        @Bean
        public ServletRegistrationBean myServletRegistrationBean() {
            ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new MyServlet(),"/myservlet");
    
            return servletRegistrationBean;
        }
    }
    

十三、使用过滤器filter

  1. 注解方式

    @WebFilter(urlPatterns = "/myfilter")
    public class MyFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("-------------------您已进入过滤器---------------------");
    
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
    
    
    @SpringBootApplication
    @ServletComponentScan(basePackages = "com.bjpowernode.springboot.filter")
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }
    
  2. 通过配置类注册组件

    public class MyFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
            System.out.println("-------------------您已进入过滤器-222-------------------");
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
    
    
    @Configuration  //定义此类为配置类
    public class FilterConfig {
    
        @Bean
        public FilterRegistrationBean myFilterRegistrationBean() {
    
            //注册过滤器
            FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new MyFilter());
    
            //添加过滤路径
            filterRegistrationBean.addUrlPatterns("/user/*");
    
            return filterRegistrationBean;
        }
    }
    

十四、设置字符编码

  1. 配置类注册组件

    @Configuration  //将此类定义为配置文件
    public class SystemConfig {
    
        @Bean
        public FilterRegistrationBean characterEncodingFilterRegistrationBean() {
    
            //创建字符编码过滤器
            CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
            //设置强制使用指定字符编码
            characterEncodingFilter.setForceEncoding(true);
            //设置指定字符编码
            characterEncodingFilter.setEncoding("UTF-8");
    
    
            FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
    
            //设置字符编码过滤器
            filterRegistrationBean.setFilter(characterEncodingFilter);
            //设置字符编码过滤器路径
            filterRegistrationBean.addUrlPatterns("/*");
    
            return filterRegistrationBean;
        }
    }
    
    
    #关闭springboot的http字符集编码支持
    #只有关闭该选项后,spring字符编码过滤器才生效
    spring.http.encoding.enabled=false
    
  2. 修改核心配置文件

    #设置请求响应字符编码
    spring.http.encoding.enabled=true
    spring.http.encoding.force=true
    spring.http.encoding.charset=utf-8
    

十五、SpringBoot打war包

  1. pom指定打war包

     <build>
            <!--指定打war包的字符-->
            <finalName>springboot</finalName>
    
            <resources>
                <resource>
                    <directory>src/main/webapp</directory>
                    <targetPath>META-INF/resources</targetPath>
                    <includes>
                        <include>*.*</include>
                    </includes>
                </resource>
    
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.*</include>
                    </includes>
                </resource>
            </resources>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
  2. 构造新资源

    @SpringBootApplication
    public class Application extends SpringBootServletInitializer {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    
            //参数为当前springboot启动类
            //构造新资源
            return builder.sources(Application.class);
        }
    }
    

十六、springboot打jar包

  1. 修改编译插件的版本

    <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>1.4.2.RELEASE</version>
                </plugin>
            </plugins>
    

十七、集成logback日志

  1. 添加logback-spring.xml配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- 日志级别从低到高分为
    TRACE < DEBUG < INFO < WARN < ERROR < FATAL,
    如果设置为 WARN,则低于 WARN 的信息都不会输出 -->
    <!--
    scan:当此属性设置为 true 时,配置文件如果发生改变,将会被重新加载,默认值为true
    -->
    <!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认
    单位是毫秒。当 scan 为 true 时,此属性生效。默认的时间间隔为 1 分钟。 -->
    <!-- debug:当此属性设置为 true 时,将打印出 logback 内部日志信息,实时查看 logback
    运行状态。默认值为 false。通常不打印 -->
    <configuration scan="true" scanPeriod="10 seconds">
        <!--输出到控制台-->
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <!--此日志 appender 是为开发使用,只配置最底级别,控制台输出的日志级别是大
            于或等于此级别的日志信息-->
            <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
                <level>debug</level>
            </filter>
            <encoder>
                <Pattern>%date [%5p] [%thread] %logger{60} [%file : %line] %msg%n
                </Pattern>
                <!-- 设置字符集 -->
                <charset>UTF-8</charset>
            </encoder>
        </appender>
    
        <!--单个定义-->
        <logger name="com.bjpowernode.springboot.mapper" level="trace"/>
    
        <!--如果root标签指定的日志级别那么以根日志级别为准,如果没有则已当前追加器日志级别为准-->
        <!--全部-->
        <!--
            appender trace  trace
            root     trace
    
            appender trace  debug
            root     debug
    
            appender trace   debug
            root     空      如果root没有值默认root级别是debug
    
            appender debug  info
            root     info
        -->
        <root level="info">
            <appender-ref ref="CONSOLE"/>
            <!--<appender-ref ref="FILE"/>-->
        </root>
    </configuration>
    
  2. 添加依赖(使用注解时使用)

    <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
    
  3. 持久层添加注释

    @Controller
    @Slf4j
    public class StudentController {
    
        @Autowired
        private StudentService studentService;
        private Logger log1;
    
        @RequestMapping(value = "/student/count")
        public @ResponseBody String studentCount() {
    
            log.trace("查询当前学生总人数");
            log.debug("查询当前学生总人数");
            log.info("查询当前学生总人数");
            log.warn("查询当前学生总人数");
            log.error("查询当前学生总人数");
    
            Integer studentCount = studentService.queryStudentCount();
    
            return "学生总人数为:" + studentCount;
        }
    }
    
    

十八、Thymeleaf模板引擎

  1. 关闭页面缓存

    #设置thymeleaf模板引擎的缓存,设置为false关闭,默认为true开启
    spring.thymeleaf.cache=false
    
  2. 设置thymeleaf前后缀

    spring.thymeleaf.prefix=classpath:/templates/
    spring.thymeleaf.suffix=.htm
    
  3. 标准变量表达式和选择变量表达式

    <h1>标准变量表达式:${} -> (推荐)</h1>
    用户编号:<span th:text="${user.id}"></span><br/>
    用户姓名:<span th:text="${user.username}"></span><br/>
    用户年龄:<span th:text="${user.age}"></span><br/>
    
    <h1>选择变量表达式(星号表达式):*{} -> (不推荐)</h1>
    <!--
        *{}必须使用th:object属性来绑定这个对象
        在div子标签中使用*来代替绑定的对象${user}
    -->
    <div th:object="${user}">
        用户编号:<span th:text="*{id}"></span><br/>
        用户姓名:<span th:text="*{username}"></span><br/>
        用户年龄:<span th:text="*{age}"></span><br/>
    </div>
    
    <h1>标准变量表达式与选择变量表达式的混合使用(不推荐)</h1>
    用户编号<span th:text="*{user.id}"></span><br/>
    用户年龄<span th:text="*{user.age}"></span><br/>
    用户姓名<span th:text="*{user.username}"></span><br/>
    
  4. url路径表达式

    <h1>URL路径表达式:@{....}</h1>
    <h2>a标签中的绝对路径(没有参数)</h2>
    <a href="http://www.baidu.com">传统写法:跳转至百度</a><br/>
    <a th:href="@{http://www.bjpowernode.com}">路径表达式:路径到动力节点</a><br/>
    <a th:href="@{http://localhost:8080/user/detail1}">跳转至:/user/detail1</a><br/>
    <a href="http://localhost:8080/user/detail1">传统写法跳转至:/user/detail1</a><br/>
    
    <h2>URL路径表达式,相对路径[没有参数](实际开发中推荐使用的)</h2>
    <a th:href="@{/user/detail1}">跳转至:/user/detail1</a><br/>
    
    <h2>绝对路径(带参数)(不推荐使用)</h2>
    <a href="http://localhost:8080/test?username='zhangsan'">绝对路径,带参数:/test,并带参数username</a><br/>
    <a th:href="@{http://localhost:8080/test?username=zhangsan}">路径表达工写法,带参数:/test,并带参数username</a><br/>
    
    <h2>相对路径(带参数)</h2>
    <a th:href="@{/test?username=lisi}">相对路径,带参数</a>
    
    <h2>相对路径(带参数:后台获取的参数值)</h2>
    <!--/test?username=1001-->
    <a th:href="@{'/test?username='+${id}}">相对路径:获取后台参数值</a>
    
    <h2>相对路径(带多个参数:后台获取的参数值)</h2>
    <!--
        /test1?id=1001&username=zhaoliu&age=28
    -->
    <a th:href="@{'/test1?id='+${id}+'&username='+${username}+'&age='+${age}}">相对路径(带多个参数:后台获取的参数值)</a>
    <a th:href="@{/test1(id=${id},username=${username},age=${age})}">强烈推荐使用:@{}相对路径(带多个参数:后台获取的参数值)</a><br/>
    <a th:href="@{'/test2/'+${id}}">请求路径为RESTful风格</a><br/>
    <a th:href="@{'/test3/'+${id}+'/'+${username}}">请求路径为RESTful风格</a><br/>
    
    <script type="text/javascript" th:src="@{/js/jquery-1.7.2.min.js}"></script>
    <script type="text/javascript">
        $(function () {
            alert("------");
            alert($("#username").val());
    
        });
    </script>
    <input type="text" id="username" value="999">
    <img th:src="@{/img/001.jpg}">
    
  5. 遍历list集合

    <!--
        user 当前循环的对象变量名称(随意)
        userStat 当前循环对象状态的变量(可选默认就是对象变量名称+Stat)
        ${userList} 当前循环的集合
    -->
    <div th:each="user,userStat:${userList}">
        <span th:text="${userStat.index}"></span>
        <span th:text="${userStat.count}"></span>
        <span th:text="${user.id}"></span>
        <span th:text="${user.nick}"></span>
        <span th:text="${user.phone}"></span>
        <span th:text="${user.address}"></span>
    </div>
    
    <div></div>
    <div th:each="user:${userList}">
        <span th:text="${userStat.index}"></span>
        <span th:text="${userStat.count}"></span>
        <span th:text="${user.id}"></span>
        <span th:text="${user.nick}"></span>
        <span th:text="${user.phone}"></span>
        <span th:text="${user.address}"></span>
    </div>
    
  6. 遍历map集合

    <div th:each="userMap,userMapStat:${userMaps}">
        <span th:text="${userMapStat.count}"></span>
        <span th:text="${userMapStat.index}"></span>
        <span th:text="${userMap.key}"></span>
        <span th:text="${userMap.value}"></span>
        <span th:text="${userMap.value.id}"></span>
        <span th:text="${userMap.value.nick}"></span>
        <span th:text="${userMap.value.phone}"></span>
        <span th:text="${userMap.value.address}"></span>
    </div>
    <div>
    
    </div>
    
    <div th:each="userMap:${userMaps}">
        <span th:text="${userMapStat.count}"></span>
        <span th:text="${userMapStat.index}"></span>
        <span th:text="${userMap.key}"></span>
        <span th:text="${userMap.value}"></span>
        <span th:text="${userMap.value.id}"></span>
        <span th:text="${userMap.value.nick}"></span>
        <span th:text="${userMap.value.phone}"></span>
        <span th:text="${userMap.value.address}"></span>
    </div>
    
  7. 遍历数组

    <h1>循环遍历Array数组(使用方法同list一样)</h1>
    <div th:each="user,userStat:${userArray}">
        <span th:text="${userStat.index}"></span>
        <span th:text="${userStat.count}"></span>
        <span th:text="${user.id}"></span>
        <span th:te7ext="${user.phone}"></span>
        <span th:text="${user.address}"></span>
    </div>
    
  8. 条件判断

    <h1>th:if 用法:如果满足条件显示(执行),否则相反</h1>
    <div th:if="${sex eq 1}"></div>
    <div th:if="${sex eq 0}"></div>
    
    <h1>th:unless 用法:与th:if用法相反,即条件判断取反</h1>
    <div th:unless="${sex ne 1}"></div>
    
    <h1>th:switch/th:case用法</h1>
    <div th:switch="${productType}">
        <span th:case="0">产品0</span>
        <span th:case="1">产品1</span>
        <span th:case="*">无此产品</span>
    </div>
    
  9. 内敛表达式

    <body th:inline="text">
    
    <h1>内敛文本: th:inline="text"</h1>
    <div th:inline="text">
    
        数据:[[${data}]]
    
    </div>
    
    数据outside:[[${data}]]
    
    <h1>内敛脚本 th:inline="javascript"</h1>
    <script type="text/javascript"  th:inline="javascript">
        function showData() {
            alert([[${data}]]);
            alert("----");
        }
    </script>
    <button th:onclick="showData()">展示数据</button>
    
  10. 字面量

    
        不成功
    </div>
    
    <h1>null字面量</h1>
    <span th:text="${user.id}"></span>
    <div th:unless="${userDetail eq null}">
        对象已创建,地址不为空
    </div>
    
    <div th:if="${userDetail.id eq null}"></div>
    
  11. 字符串拼接

    <h1>使用更优雅的方式来拼接字符串: |要拼接的字符串内容|</h1>
    
    <span th:text="|共${totalRows}条${totalPage}页,当前第${currentPage}页,首页 上一页 下一页 尾页|">共120条12页,当前第1页,首页 上一页 下一页 尾页</span>
    
  12. 数字运算

    <!--
        三元运算 :表达式?” 正确结果”:” 错误结果”
        算术运算: :+ , - , * , / , %
        关系比较: :> , < , >= , <= ( gt , lt , ge , le )
        相等判断: :== , != ( eq , ne )
    
        ne -> not equal
        eq -> equal
        ge -> great equal
        le -> little equal
        gt -> great
        lt -> little
    -->
    <h1>三元运算符 表达式?正确:错误</h1>
    <div th:text="${sex eq 1 ? '':''}"></div>
    <div th:text="${sex == 1 ? '':''}"></div>
    
    <h1>算术运算</h1>
    20+5=<span th:text="20+5"></span><br/>
    20-5=<span th:text="20-5"></span><br/>
    20*5=<span th:text="20*5"></span><br/>
    20/5=<span th:text="20/5"></span><br/>
    20%3=<span th:text="20%3"></span><br/>
    
    <h1>关系比较</h1>
    5>2为<span th:if="5 gt 2"></span><br/>
    5>2为<span th:if="5 > 2"></span><br/>
    5<2<span th:unless="5 lt 2"></span><br/>
    5<2<span th:unless="5 < 2"></span><br/>
    1>=1<span th:if="1 ge 1"></span><br/>
    1>=1<span th:if="1 >= 1"></span><br/>
    1<=1<span th:if="1 le 1"></span><br/>
    1<=1<span th:if="1 <= 1"></span><br/>
    
    <h1>相等判断</h1>
    <span th:if="${sex == 1}"></span>
    <span th:if="${sex eq 1}"></span>
    <span th:unless="${sex ne 1}"></span>
    
  13. 基本表达式对象

    <h1>从SESSION中获取值</h1>
    <span th:text="${#session.getAttribute('data')}"></span><br/>
    <span th:text="${#httpSession.getAttribute('data')}"></span><br/>
    <span th:text="${session.data}"></span><br/>
    
    <script type="text/javascript" th:inline="javascript">
        // http://localhost:8080/springboot/user/detail
        //获取协议名称
        var scheme = [[${#request.getScheme()}]];
    
        //获取服务器名称
        var serverName = [[${#request.getServerName()}]];
    
        //获取服务器端口号
        var serverPort = [[${#request.getServerPort()}]];
    
        //获取上下文根
        var contextPath = [[${#request.getContextPath()}]];
    
        var allPath = scheme + "://" +serverName+":"+serverPort+contextPath;
    
        var requestURL = [[${#httpServletRequest.requestURL}]];
        var queryString = [[${#httpServletRequest.queryString}]];
    
        var requestAddress = requestURL + "?" +queryString;
    
        alert(requestAddress);
    </script>
    
  14. 功能表达式对象

    <div th:text="${time}"></div>
    <div th:text="${#dates.format(time,'yyyy-MM-dd HH:mm:ss')}"></div>
    <div th:text="${data}"></div>
    <div th:text="${#strings.substring(data,0,10)}"></div>
    <div th:text="${#lists}"></div>
    

十九、核心配置文件补充

#关闭logo
spring.mian.banner-mode=off
#项目类型   servlet表示web项目 nome表示java项目
spring-main.web-application-type=servlet
#指定配置类
spring-main-source=com.wangxiangqian.DemoApplication
#延迟初始化
spring.main.lazy-initialization=true
#配置随机值,通过配置文件得到一个随机值,springboot提供RandomValuePropertySource可用于注入随机值(例如,注入一些随机值或测试用例),它可以产生整数,longs,uuid或字符串,如下示例所示:
my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

#配置文件中可以使用占位符:
my.name = cat
my.desc = ${my.name} is a teacher.

#Duration单位转换
server.servlet.session.timeout=1800s
server.servlet.session.timeout=30m
server.servlet.session.timeout=PT30m

#DataSize 类型单位转换
server.tomcat.max-swallow-size=2048KB

二十、Jasypt敏感信息加密

  1. 依赖

    <dependency>
        <groupId>com.github.ulisesbocchio</groupId>
        <artifactId>jasypt-spring-boot-starter</artifactId>
        <version>3.0.3</version>
    </dependency>
    
    
  2. 密钥

    #加密解密的密钥key
    jasypt.encryptor.password=1234
    #加密信息
    spring.datasource.username=ENC(44WdFjkoq6IQsutoeACsTAzdu8W6qPPbievCkJ36tJ9l5IYaVpkUK+NpPG9uPCFc)
    spring.datasource.password=ENC(4YGp/Ps1lrkf4dJfN85JLLY35lCMvrGJP39ucrw/8gO9G9NNCh8XiN0zABKQr0jF)
    
  3. 应用

    @SpringBootTest
    class ApplicationTests {
        @Autowired
        private StringEncryptor stringEncryptor;
        @Test
        public void encryptPwd() {
        //加密
        String username = stringEncryptor.encrypt("root");
        System.out.println("加密username: " + username);
    
        String decUsername = stringEncryptor.decrypt(username);
        System.out.println("解密username: " + decUsername);
    
        //加密
        String password = stringEncryptor.encrypt("123456");
        System.out.println("password: " + password);
        String decPassword = stringEncryptor.decrypt(password);
        System.out.println("解密password: " + decPassword);
      }
    }
    
    

二十一、springboot数据库连接池

  1. 默认是HikariCP数据库连接池

  2. 修改数据库连接池(第一种方式)

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.3</version>
        <exclusions>
            <!--排除掉HikariCP数据库连接池-->
            <exclusion>
                <groupId>com.zaxxer</groupId>
                <artifactId>HikariCP</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.23</version>
    </dependency>
    
    
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    
  3. 修改数据库连接池(第二种方式)

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.23</version>
    </dependency>
    
    

二十二、SpringBoot跨域资源共享CORS支持

  1. 第一种方式
    //设置配置bean
    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/web/**");
                registry.addMapping("/boot/**");
            }
        };
    }
    
    
  2. 第二种方式
@Configuration
public class MyConfig implements WebMvcConfigurer {


    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/web/**");
        registry.addMapping("/boot/**");
    }
}
  1. jsonp跨域请求

    $.ajax({
            type:"GET",
            url:"http://192.168.0.104:8080/boot/test",
            dataType : "jsonp", //返回的数据类型,设置为JSONP方式
            jsonp : 'callback', //覆盖默认的 jsonp回调参数名callback
            jsonpCallback: 'handleResponse', //设置回调函数名
            success: function(response, status, xhr){
                console.log('状态为:' + status + ',状态是:' + xhr.statusText);
                console.log(response);
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                // 状态码
                console.log(XMLHttpRequest.status);
                // 状态
                console.log(XMLHttpRequest.readyState);
                // 错误信息
                console.log(textStatus);
                console.log(errorThrown);
            }
        });
    });
    function handleResponse(response){
        console.log(response);
    }
    
    
    @RequestMapping("/web/jsonp")
    public @ResponseBody Object jsonp(){
    	Map<String,String> map = new HashMap<>();
    	map.put("k1","v1");
    	map.put("k2","v3");
    	return handleResponse({\"k1\":\"v1\",\"k2\":\"v3\"});
    }
    
  2. CORS与JSONP比较
    CORS与JSONP都是为了跨域,但是CORS比JSONP更强大;
    JSONP只支持GET请求,CORS支持所有类型的HTTP请求;
    JSONP的优势在于支持老式浏览器;

二十三、静态资源的处理

Spring Boot默认静态资源目录位置位于classpath下,目录名需符合如下规则:
有4个目录下的静态资源可以直接访问:
/static
/public
/resources
/META-INF/resources
#自己修改静态资源文件的位置
spring.resources.static-locations=classpath:/mysource/

二十四、SpringBoot开发最佳实践

1、SpringBoot 程序,每个类应该有一个包,没有包的话会出现问题;
2、一个合理的包结构:
 
3、我们通常建议您将主应用程序类放在其他类之上的根包中,主类上需要有一个@SpringBootApplication注解,默认是扫描当前包及子类下的标有@Component, @Service, @Repository, @Controller等注解的bean;
4、如果main类上不使用@SpringBootApplication注解,可以使用@EnableAutoConfiguration、@ComponentScan、@Configuration 注解代替;
5、main方法的类也是一个配置类,也是ioc容器中的一个bean,Springboot不推荐使用xml配置方式;
6、还可以通过@Import导入其他bean对象(组件),或者通过@Configuration加入bean组件,或者@Configuration+@Bean,或者@Configuration+@ComponentScan加入bean对象(组件);
7、也可以通过@ImportResource(locations = "classpath:applicationContext.xml")加入xml配置的bean对象(组件);
8、禁止某些自动配置:@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
或者在配置文件中 spring.autoconfigure.exclude= 进行排除,可以达到优化程序的效果;
9、springboot内嵌了web服务器,所以打成一个jar包即可运行,方便我们的开发和调试;
10、延迟初始化bean:spring.main.lazy-initialization=true
ApplicationContext context = new SpringApplicationBuilder()
        .lazyInitialization(true)
        .sources(com.bjpowernode.Application.class)
        .bannerMode(Banner.Mode.CONSOLE)
        .run(args);

SpringApplication springApplication = new SpringApplication(Application.class);
springApplication.setLazyInitialization(true);

如果要禁用某些bean的延迟初始化,则可以使用@Lazy(value=false)注解将它们的延迟属性显式设置为false;

SpringApplication启用延迟初始化后,将根据需要创建bean,而不是在应用程序启动期间创建bean,因此启用延迟初始化可以减少启动应用程序所需的时间。在Web应用程序中,启用延迟初始化将导致许多与Web相关的Bean直到收到HTTP请求后才被初始化。延迟初始化的缺点是,它可能会延迟发现应用程序的问题。如果错误地配置了Bean的延迟初始化,则可能导致启动时没有问题,在访问调用的时候出现问题,另外还必须注意确保JVM有足够的内存来容纳所有应用程序的bean,而不仅仅是启动过程中初始化的bean,由于这些原因,默认情况下SpringBoot不会开启延迟初始化;
11、CommandLineRunner, ApplicationRunner在springboot启动后回调着两个接口里面的run方法;

二十四、SpringBoot线程池异步调用

  1. SpringBoot框架自动装配提供了一个的线程池,用于提交异步任务;
    有了线程池我们就只需要写任务即可,提交任务采用@Async注解;(底层是aop)
    Springboot自动装配提供的线程池还可以根据需要进行配置:

    #SpringBoot配置线程池,修改线程池默认配置
    spring.task.execution.pool.max-size=99999
    spring.task.execution.thread-name-prefix=cat-task-
    spring.task.execution.pool.queue-capacity=99999
    
    
  2. 我们也可以覆盖SpringBoot自动配置的线程池,用我们自定义的线程池:

    @Bean
    public ThreadPoolTaskExecutor asyncExecutor() {
        logger.info("start asyncExecutor......");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心线程数
        executor.setCorePoolSize(16);
        //配置最大线程数
        executor.setMaxPoolSize(64);
        //配置队列大小
        executor.setQueueCapacity(9999);
        //配置线程池中的线程的名称前缀
        executor.setThreadNamePrefix("async-order-");
        // rejection-policy:当pool已经达到max pool size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是由调用线程(提交任务的线程)处理该任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }
    
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值