Spring Boot

Posted 小企鹅推雪球!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot相关的知识,希望对你有一定的参考价值。

@RestController 注解

  1. 在Spring中@RestController的作用等同于@Controller + @ResponseBody 注解

  2. @RestController所有带有此注解的类将被视为控制器(Controller),其中 @RequestMapping方法默认情况下均采用 @ResponseBody语义

  3. 需要开发一个获取当前日期的接口,该接口将采用“yyyy-MM-dd HH:mm:ss.SSS”格式返回日期

    1. 需要开发一个获取当前日期的接口,该接口将采用“yyyy-MM-dd HH:mm:ss.SSS”格式返回日期
      package com.huangx.springboot.springboot_restcontroller_demo1;
       
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      import java.text.SimpleDateFormat;
      import java.util.Date;
       
      @Controller
      @RequestMapping("/demo1")
      public class Demo1Controller 
          /**
           * 获取当前日期
           * @return
           */
          @RequestMapping("/getDate")
          @ResponseBody
          public String getDate() 
              String pattern = "yyyy-MM-dd HH:mm:ss.SSS";
              SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
              return dateFormat.format(new Date());
          
      
    2. 使用 @Controller 注解将 Demo1Controller 类声明成一个控制器,然后在 getDate() 方法上面添加 @ResponseBody 注解。
  4. @ResponseBody注解的作用是将控制器的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到Response对象的body区,通常用来返回JSON数据或者是XML数据

  5. 使用@ResponseBody注解之后不会再走视图处理器,而是直接将数据写入到输出流中,

  6. @ResponseBody注解的效果等同于通过Response对象输出指定格式的数据。

  7. 为了获取当前日期,使用 @Controller 和 @ResponseBody 两个注解,并且 @ResponseBody 注解需要添加到每个接口方法上

  8. Spring 为了开发便捷,提供了 @RestController 方法

    package com.huangx.springboot.springboot_restcontroller_demo1;
     
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import java.text.SimpleDateFormat;
    import java.util.Date;
     
    @RestController
    @RequestMapping("/demo2")
    public class Demo2Controller 
        /**
         * 获取当前日期
         * @return
         */
        @RequestMapping("/getDate")
        public String getDate() 
            String pattern = "yyyy-MM-dd HH:mm:ss.SSS";
            SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
            return dateFormat.format(new Date());
        
    
    	```
    
    

@ComponentScan 注解

  1. @ComponentScan 注解主要是定义扫描的包路径,然后从中找出标识了需要装配的类自动装配到Spring的Bean容器
  2. @ComponentScan 注解默认就会装配标识了 @Controller、@Service、@Repository 和 @Component 注解的类到 Spring 容器中
  3. @ComponentScan注解支持如下属性
    1. Class<?>[] basePackageClasses:basePackages() 的类型安全替代方案,用于指定要扫描的组件以扫描带注释的组件

      @ComponentScan(basePackageClasses = 
              IndexController.class,
              DateController.class
      )
      // 扫描 com.huangx.springboot.controller 和 com.huangx.springboot.controller2 包以及子包
      
    2. String[] basePackages:用于扫描带注解的组件的基本包

      @ComponentScan(basePackages = 
              "com.huangx.springboot.controller",
              "com.huangx.springboot.controller2"
      )
       
      @ComponentScan(
              "com.huangx.springboot.controller",
              "com.huangx.springboot.controller2"
      )
      // 扫描 com.huangx.springboot.controller 和 com.huangx.springboot.controller2 包以及子包
      
    3. ComponentScan.Filter[] excludeFilters:指定哪些类型不符合组件扫描的条件

      @ComponentScan(basePackages = 
      	        "com.huangx.springboot.controller",
      	        "com.huangx.springboot.controller2"
      	    , excludeFilters = 
      	        // 根据注解类型过滤,过滤拥有 MyAnnotation 注解的 Bean
      	        @ComponentScan.Filter(type = FilterType.ANNOTATION, classes =  MyAnnotation.class ),
      	        // 使用自定义的过滤器过滤Bean
      	        @ComponentScan.Filter(type = FilterType.CUSTOM, classes =  MyTypeFilter.class ),
      	        // 使用正则表达式过滤Bean, 下面将过滤 DateController 类
      	        @ComponentScan.Filter(type = FilterType.REGEX, pattern =  ".+DateController" ),
      	        // 使用 AspectJ 表达式过滤 com.huangx.springboot.controller2 包及子包下面所有类的所有方法
      	        @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern =  "com.huangx.springboot.controller2..*" )
      	    
      	)
      
    4. ComponentScan.Filter[] includeFilters:指定哪些类型适合进行组件扫描

      定义的 @ComponentScan.Filter 有效,必须将 useDefaultFilters 设置为 false
      @ComponentScan(basePackages = 
              "com.huangx.springboot.controller",
              "com.huangx.springboot.controller2"
          , includeFilters = 
              // 根据注解类型过滤,过滤拥有 MyAnnotation 注解的 Bean
              @ComponentScan.Filter(type = FilterType.ANNOTATION, classes =  MyAnnotation.class ),
              // 使用自定义的过滤器过滤Bean
              @ComponentScan.Filter(type = FilterType.REGEX, pattern = 
                      "com.huangx.springboot.controller.model.*"
              )
          , useDefaultFilters = false
      )
      
    5. boolean lazyInit:指定是否应该为延迟初始化注册扫描bean

      @ComponentScan(basePackages = 
              "com.huangx.springboot.controller",
              "com.huangx.springboot.controller2",
              lazyInit = true
      )
      

@ComponentScans 注解

  1. @ComponentScans 注解可以一次声明多个 @ComponentScan 注释

  2. @ComponentScans 注解可以本地使用,声明几个嵌套的 @ComponentScan 注解。也可以与 Java 8 对可重复注释的支持结合使用

  3. @ComponentScans 可以简单地在同一方法上多次声明 @ComponentScan,从而隐式生成此容器注释

  4. 在 @ComponentScans 注解中声明了两个 @ComponentScan 注解

    @ComponentScans(
        @ComponentScan(basePackages = 
            "com.huangx.springboot.controller"
        , includeFilters = 
            // 仅仅使用了 @RestController 注解声明的类
            @ComponentScan.Filter(type = FilterType.ANNOTATION, classes =  RestController.class )
        , useDefaultFilters = false),
        @ComponentScan(basePackages = 
            "com.huangx.springboot.controller2"
        , excludeFilters = 
            // 过滤使用了 @MyAnnotation 注解的类
            @ComponentScan.Filter(type = FilterType.ANNOTATION, classes =  MyAnnotation.class )
        )
    )
    public class MyConfig 
         
    
    
  5. 第一个 @ComponentScan 注解将扫描 com.huangx.springboot.controller 包及子包下面声明了 @RestController 注解的类

  6. 第二个 @ComponentScan 注解将过滤 com.huangx.springboot.controller2 包及子包下声明了 @MyAnnotation 注解的类

@ImportResource 注解

  1. @ImportResource 注解用于导入 Spring 的配置文件,如:spring-mvc.xml、application-Context.xml

  2. Spring Boot 里面没有Spring 配置文件,都是通过 Java 代码进行配置。如果我们自己编写了配置文件,Spring Boot 是不能自动识别,此时需要使用 @ImportResource 注解将自己的配置文件加载进来

  3. @ImportResource 注解的可选属性

    1. String[] locations:要导入的资源路径,如:classpath:spring-mvc.xml 从类路径加载 spring-mvc.xml 配置文件。
    2. Class<? extends BeanDefinitionReader> reader:在处理通过 value() 属性指定的资源时使用的 BeanDefinitionReader 实现
    3. String[] value:locations() 的别名
  4. 在 resources 目录下面创建一个 application-context.xml 文件,该文件中手动声明一个 Bean,然后在 Controller 中引用

  5. application-context.xml 配置文件内容如下

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="dateBean" class="com.huangx.springboot.demo1.bean.DateBean" />
    </beans>
    
  6. 定义 DateBean

    public class DateBean 
        private static final SimpleDateFormat DF =
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        private String currentDate;
     
        public DateBean init() 
            this.currentDate = DF.format(new Date());
            return this;
        
     
        public String getCurrentDate() 
            return currentDate;
        
     
        public void setCurrentDate(String currentDate) 
            this.currentDate = currentDate;
        
    
    
  7. 在客户端中使用 @Autowired 注入 DateBean 对象。然后调用它的 init() 和 getCurrentDate() 方法

    @ImportResource(locations = "classpath:application-context.xml")
    @RestController
    @SpringBootApplication
    public class Demo1Application 
     
        @Autowired
        private DateBean dateBean;
     
        public static void main(String[] args) 
            SpringApplication.run(Demo1Application.class, args);
        
     
        @RequestMapping("/")
        public String index() 
            if(null == dateBean) 
                return "-";
             else 
                return dateBean.init().getCurrentDate();
            
        
     
    
    
  8. @ImportResource(locations = “classpath:application-context.xml”) 代码可以简写为 @ImportResource(“classpath:application-context.xml”)。

@Import 注解

  1. @Import 注解用来导入的一个或多个组件类,通常是 @Configuration 类,也可以是普通类。提供与 Spring XML 中的 元素相同的功能
  2. . @Import 注解允许导入 @Configuration 类,导入的 @Configuration 类中声明的 @Bean 定义可以使用 @Autowired 注解注入进行访问。可以对 bean 本身进行自动装配,也可以对声明 bean 的配置类实例进行自动装配。
  3. 声明 bean 的配置类实例进行自动装配时, 允许在@Configuration 类方法之间进行显式的,IDE 友好的导航
  4. 如果需要导入 XML 或其他非 @Configuration bean 定义资源,使用 @ImportResource 注解。
  5. @Import 注解最常见的使用方式:
    1. 导入带有 @Configuration 注解的配置类,注意:4.2 版本之前只可以导入配置类,4.2 版本之后也可以导入普通类

@Import 注解加载普通类

  1. 定义一个 MyBean

    import java.text.SimpleDateFormat;
    import java.util.Date;
     
    public class MyBean 
        private String date;
     
        public MyBean init() 
            this.date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            return this;
        
     
        public String getDate() 
            return date;
        
     
        public void setDate(String date) 
            this.date = date;
        
     
    
    
  2. 在 Spring Boot 启动类上面使用 @Import 注解加载 MyBean 类

    /**
     * 加载普通类
     */
     // 这里可以一次加载多个类,例如:@Import( MyBean.class, MyBean2.class, MyBean3.class )
    @Import( MyBean.class )
    @RestController
    @SpringBootApplication
    public class Demo1Application 
     
        @Autowired
        private MyBean myBean;
     
        public static void main(String[] args) 
            SpringApplication.run(Demo1Application.class, args);
        
     
        @RequestMapping("/")
        public String index() 
            return myBean.init().getDate();
        
     
    
    
  3. 加载配置类:配置类中的 MyBean 沿用上面定义的 MyBean 类

  4. 定义自己的配置类 MyConfig,注意,该配置类上面没有添加 @Configuration 注解,因此不会自动被加载

    import com.huangx.springboot.springboot_import_demo1.bean.MyBean;
    import org.springframework.context.annotation.Bean;
     
    public class MyConfig 
     
        @Bean
        public MyBean getMyBean() 
            System.out.println("Init MyBean");
            return new MyBean();
        
     
    
    
  5. 使用 @Import 注解手动加载 MyConfig 配置类

     
    /**
     * 加载配置类
     */
    @Import( MyConfig.class )
    @RestController
    @SpringBootApplication
    public class Demo1Application 
     
        @Autowired
        private MyBean myBean;
     
        public static void main(String[] args) 
            SpringApplication.run(Demo1Application.class, args);
        
     
        @RequestMapping("/")
        public String index() 
            return myBean.init().getDate();
        
     
    
    

@Bean 注解

  1. @Bean 注解指示方法生成由 Spring 容器管理的 Bean,

  2. @Bean 注解属性的名称和语义有意类似于Spring XML模式中的 元素的名称和语义

    @Bean
    public MyBean myBean() 
        // instantiate and configure MyBean obj
        return obj;
    
    
  3. Bean名称:当 name() 属性可用时,确定bean名称的默认策略是使用@Bean方法的名称,如果需要显式命名,则可以使用name属性(或其别名值

  4. name接受一个字符串数组,允许为单个bean使用多个名称(即主bean名称加上一个或多个别名)

    @Bean("b1", "b2") // bean available as 'b1' and 'b2', but not 'myBean'
    public MyBean myBean() 
        // instantiate and configure MyBean obj
        return obj;
    
    
  5. @Bean 注解不提供 profile、scope、lazy、depends-on 或 primary 属性

  6. @Bean 注解 与 @Scope、@Lazy、@DependsOn 和 @Primary 注解结合使用以声明这些语义

    1. @Profile 允许选择性地包含某些 bean
    2. @Scope 将 bean 的范围从单例更改为指定的范围
    3. @Lazy 仅在默认单例作用域的情况下才具有实际效果
    4. @DependsOn 会在创建此 bean 之前强制创建特定的其他 bean,以及该 bean 通过直接引用表示的任何依赖关系
    5. @Primary 是一种机制,用于在注入点级别解决歧义性,如果需要注入单个目标组件,但多个 bean 按类型匹配。

@Lazy 注解

  1. Spring IoC(ApplicationContext)容器一般都会在启动的时候实例化所有单实例 Bean
  2. 如果想要 Spring 在启动的时候延迟加载 Bean,即在调用某个 Bean 的时候再去初始化,那么就可以使用 @Lazy 注解
  3. @Lazy 注解用来告诉 Spring 是否要延迟初始化指定的Bean
  4. @Lazy注解可用于直接或间接用了 @Component 注解的任何类,或用了@Bean注释的方法
  5. 如果 @Component 或 @Bean 定义上不存在 @Lazy 注解,则会进行初始化
  6. 如果存在 @Lazy 注解且设置 value为true,则 @Bean或 @Component 定义的 Bean 将不会被初始化,直到被另一个 Bean 引用或从封闭的 BeanFactory 中显式检索
  7. 如果存在 @Lazy 且设置 value 为false,则将在执行启动单例初始化的Bean工厂启动时实例化Bean
  8. 如果 @Configuration 类上存在 @Lazy 注解,则表明该 @Configuration 中的所有 @Bean 方法都应延迟初始化。
  9. 如果在 @Lazy 注解的 @Configuration 类中的 @Bean方法上存在 @Lazy 注解且设置 value 为 false,则表明重写了“默认延迟”行为,并且应立即初始化Bean。
    10.value() 是否应该进行延迟初始化,true 表示开启延迟初始化,false 表示不开启延迟初始化。默认为 true。

@Lazy 注解样例

  1. 定义一个 MyConfig 类,该类上面添加了 @Lazy 注解,该注解将延迟该类下的 myBean 初始化,只有当我们用到 MyBean 的时候才会去初始化

    @Configuration
    @Lazy
    public class MyConfig 
     
        @Bean
        public MyBean myBean() 
            System.out.println("===> init MyBean");
            return new MyBean("Welcome to SpringBoot.");
        
     
    
    
  2. 定义了 MyConfig2 类,该类有两个 @Bean 方法,一个返回 MyBena2,另一个返回 ArrayList,其中 myBean2() 方法上面有 @Lazy 注解,表示该 Bean 将延迟初始化

    @Configuration
    public class MyConfig2 
     
        @Bean
        @Lazy
        public MyBean2 myBean2() 
            System.out.println("===> init MyBean2");
            return new MyBean2("Welcome to SpringBoot.");
        
     
        @Bean
        public ArrayList arrayList() 
            System.out.println("===> init ArrayList");
            return new ArrayList<>();
        
     
    
    
  3. 定义客户端调用前面 MyConfig 和 MyConfig2 中定义的 Bean,用来验证 Bean 是否在使用的时候才初始化

    @SpringBootApplication
    @RestController
    public class SpringbootLazyDemo1Application 
     
        @Autowired
        private ApplicationContext applicationContext;
     
        public static void main(String[] args) 
            SpringApplication.run(SpringbootLazyDemo1Application.class, args);
        
     
     
        @RequestMapping("/demo1")
        public String demo1() 
            MyBean myBean = applicationContext.getBean(MyBean.class);
            return myBean.getSummary();
        
     
        @RequestMapping("/demo2")
        public String demo2() 
            MyBean2 myBean = applicationContext.getBean(MyBean2.class);
            return myBean.getSummary();
        
     
    
    

以上是关于Spring Boot的主要内容,如果未能解决你的问题,请参考以下文章

一张图,理顺 Spring Boot应用在启动阶段执行代码的几种方式

一张图帮你记忆,Spring Boot 应用在启动阶段执行代码的几种方式

一张图,理顺 Spring Boot应用在启动阶段执行代码的几种方式

一张图,理顺 Spring Boot应用在启动阶段执行代码的几种方式

Spring Boot部署JAR文件瘦身优化经验分享

带有分页和排序的 Spring Boot JPA 规范 API