04springboot

第1章 Spring Boot 基础

1.1 Spring Boot 工程的创建

1)jarwar区别

jar包使用springBoot内置tomcat服务器
war包部署时,需要外部的 web 容器,例如JBOSS、WebLogic

1.2 SpringBoot 的配置文件

1)yml配置文件

server:
  port: 8088
  servlet:
    context-path: /test

2)properties配置文件

server.port=8088
server.servlet.context-path=/test

1.3 Actuator 监控器

  • 导入依赖

    <dependency> 
       <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-starter-actuator</artifactId> 
    </dependency>
    
  • 修改properties配置文件

    # Actuator的端口号及上下文路径
    management.server.port=9999
    management.server.servlet.context-path=/first
    
    # 指定默认路径
    management.endpoint.web.base-path=/base
    
  • 访问测试—health 监控终端

    localhost:9999/first/base/health
    

第2章 Spring Boot 工程应用

2.1 自定义异常页面

  • src/main/resources 目录下再定义新的目录public/error必须是这个目录名称。

  • 在error 目录中定义异常页面。这些异常页面的名称必须为相应的状态码,扩展名为html。例如:404.html(3/0时出现)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>404</title>
    </head>
    <body>
        404 错误
    </body>
    </html>
    

2.2 单元测试

2.3 多环境选择

1)application.yml

spring:
  profiles:
    active: dev   	# dev开发环境
#    active: prod	#prod生产环境

2)application-dev.yml

server:
  port: 8081
  servlet:
    context-path: /dev

3)application-prod.yml

server:
  port: 8082
  servlet:
    context-path: /prod

2.4 读取自定义配置

1)读取单个属性

@Value("${server.port}")
private int port;

2)读取多个配置文件

@Component
@PropertySource(value = "classpath:custom.properties", encoding = "utf-8") //properties格式配置
//@PropertySource(value = "classpath:custom1.yml", encoding = "utf-8", factory = YamlPropertySourceF.class) //yml格式配置----需要配置
@ConfigurationProperties(prefix = "student") 	//指定
@Data
public class Student {

    private String name;	//变量名必须与配置文件中的名称一致,否则读不到数据
    private int age;
    private double score;
}

2.5 Spring Boot 下使用JSP 页面

  • 在src/main 下创建webapp 目录,用于存放jsp 文件。这就是一个普通的目录,无需执行Mark Directory As。

  • 在spring boot 工程中若要创建jsp 文件,一般是需要在src/main 下创建webapp 目录,然后在该目录下创建jsp 文件。但通过Alt + Insert 发现没有创建jsp 文件的选项。此时,需要打开Project Structrue 窗口,选择Facets->Web->添加Web Resoure Directory,将webapp 目录指定为web 资源目录,然后才可以创建jsp文件。

  • index.jsp文件

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <meta charset="utf-8">
        <title>测试标题</title>
    </head>
    <body>
        <form action="test/jsp" method="post">
            年龄:<input type="text" name="age"><br>
            姓名:<input type="text" name="name"><br>
            <input type="submit" name="注册">
        </form>
    
    </body>
    </html>
    
  • welcome.jsp

  • <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
        name=${name}<br>
        age=${age}<br>
    </body>
    </html>
    
  • 在pom 中添加一个Tomcat 内嵌的jsp 引擎jasper 依赖。jsp 引擎是用于解析jsp 文件的,
    即将jsp 文件解析为Servlet 是由jsp 引擎完成的。embed,嵌入。

    <dependency> 
        <groupId>org.apache.tomcat.embed</groupId> 
        <artifactId>tomcat-embed-jasper</artifactId> 
    </dependency> 
    
  • 在pom 文件中将webapp 目录注册为资源目录。

    <build> 
        <resources> 
            <!--注册webapp 目录为资源目录--> 
            <resource> 
               <directory>src/main/webapp</directory> 
    		   <targetPath>META-INF/resources</targetPath> 
                <includes> 
                    <include>**/*.*</include> 
                </includes> 
            </resource> 
        </resources> 
    </build>
    
  • controller类

    @Controller    //注意不是@RestController
    @RequestMapping("/test")
    public class JspController {
    
        @PostMapping("/jsp")
        public String jsp(String name, int age, Model model){
            model.addAttribute("name", name);
            model.addAttribute("age", age);
            return "/jsp/welcome.jsp";
            // return "jsp/welcome"; 配置下面文件
        }
    }
    
  • 修改主配置文件 (非必要)

     # 配置controller类返回值前后缀
     mvc:
        view:
          prefix: /
          suffix: .jsp
    
  • 实体类

    @Data
    public class User {
        private String name;
        private int age;
    }
    

2.6 Spring Boot 中使用MyBatis

1)总步骤

  • 导入三个pom依赖:mybatis 与Spring Boot 整合依赖mysql 驱动依赖与Druid 数据源依赖。

    <!--mybatis 与spring boot 整合依赖--> 
    <dependency> 
        <groupId>org.mybatis.spring.boot</groupId> 
        <artifactId>mybatis-spring-boot-starter</artifactId> 
        <version>1.3.2</version> 
    </dependency> 
     
    <!--mysql 驱动--> 
    <dependency> 
        <groupId>mysql</groupId> 
        <artifactId>mysql-connector-java</artifactId> 
        <version>5.1.47</version> 
    </dependency> 
     
    <!-- druid 驱动 --> 
    <dependency> 
        <groupId>com.alibaba</groupId> 
        <artifactId>druid</artifactId> 
        <version>1.1.12</version> 
    </dependency>
    
  • pom注册资源

    <resources>
    	<!--注册webapp 目录下的jsp为资源目录-->
        <resource>
            <directory>src/main/webapp</directory>
            <targetPath>META-INF/resources</targetPath>
            <includes>
                <include>**/*.*</include>
            </includes>
        </resource>
        <!--默认resource目录下的xml,其他需注册dao 包下mybatis 映射文件为资源目录-->
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
    
  • 修改主配置文件(注册xml文件,实体类,以及数据源)

    # 注册xml和实体类
    mybatis:
      mapper-locations: classpath:com/monkey/springboot/mapper/*.xml
      type-aliases-package: com.monkey.springboot.entity
    # 注册数据源
    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&autoReconnect=true&allowMultiQueries=true&useSSl=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
        username: root
        password: 1234
    

2.7 Spring Boot 的事务支持

  • 若工程直接或间接依赖于spring-tx,则框架会自动注入DataSourceTransactionManager事务管理器;

  • 依赖于spring-boot-data-jpa,则会自动注入JpaTransactionManager

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    // spring 默认事提交方式,发生异常回滚
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ)
    public void addUser(User user) {
        userDao.addUser(user);
        int a = 5/0;      //异常回滚
        userDao.addUser(user);
    }
}

2.8 Spring Boot 对日志的控制

1) logback 日志技术介绍

  • Spring Boot 中使用的日志技术为logback。其与 Log4J 都出自同一人,性能要优于Log4J,是Log4J 的替代者。

  • 在Spring Boot 中若要使用logback,则需要具有spring-boot-starter-logging 依赖,而该依赖被spring-boot-starter-web 所依赖,即不用直接导入spring-boot-starter-logging 依赖。

    # 日志控制
    logging:
      # console表示显示在控制台
      # logs-自定义前缀,level等级,msg信息,n换行
      pattern:
        console: logs-%level %msg%n
      level:
        root: info   #级别,减少项目日志
        com.monkey.springboot.dao: debug  #指定dao层日志
    
  • 添加logback.xml日志配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <appender name="log" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%-5level - %msg%n</pattern>
            </encoder>
        </appender>
    
        <root level="warn">
            <appender-ref ref="log"/>
        </root>
    
        <logger name="com.monkey.springboot.dao" level="debug"/>
    </configuration>
    

2)日志等级

tarce < debug < info < warn < error < fatal

2.9 Spring Boot 中SSRM 整合应用

1)redis分类:两类

  • (注解实现) DB更新后,Redis 缓存中的数据就要马上清除,以保证将来缓存中的数据与DB 中的数据的绝对一致性,这是一类数据;
  • (设置过期时效) 还有一类,对数据准确性要求不是很高,只要与DB 中的数据差别不大就可以,所以这类数据一般会为其设置过期时效

2)举例

1. 当前工程完成让用户在页面中输入要查询学生的id,其首先会查看Redis 缓存中是否存在,
2. 若存在,则直接从Redis 中读取;若不存在,则先从DB 中查询出来,然后再存放到Redis缓存中。
3. 但用户也可以通过页面注册学生,一旦有新的学生注册,则需要将缓存中的学生信息清空。
4. 根据id 查询出的学生信息要求必须是实时性的,其适合使用注解方式的Redis 缓存。 
5. 同时,通过页面还可以查看到总学生数,但对其要求是差不多就行,无需是实时性的。
6. 对于Spring Boot 工程,其适合使用API 方式的Redis 缓存,该方式方便设置缓存的到期时限。 

3)整合步骤

  • 修改pom 文件

    <!--redis-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  • 修改yml配置文件

    spring:
    # 单机redis
      redis:
        host: 127.0.0.1
        port: 6379
        database: 0
        timeout: 6000ms
        password:
      cache:
        type: redis        # 指定缓存类型
        cache-names: redisCache  #指定缓存区域名称(注解中使用value属性)
    
    #    #redis集群
    #    sentinel:
    #      master: mymaster
    #      nodes: sentinel1:6307,sentinel2:6307,sentinel3:6307
    
  • 代码实现-------访问: http://localhost:8080/index.jsp

    // controller类
    @Controller
    @RequestMapping("/redis")
    public class UserRedisController {
        @Autowired
        private UserRedisService userRedisService;
    
        @PostMapping("/addUser")
        public String addUser(User user, Model model){
            model.addAttribute("name", user.getName());
            model.addAttribute("age", user.getAge());
            userRedisService.addUser(user);
            return "/jsp/userRedis.jsp";
        }
    
        @PostMapping("/selectAge")
        public String addUser(int age, Model model){
            model.addAttribute("age", age);
            userRedisService.selectAge(age);
            return "/jsp/userRedis.jsp";
        }
    
        @GetMapping("/selectCount")
        public String selectCount(){
            int count = userRedisService.selectCount();
            return "/jsp/userRedis.jsp";
        }
    }
    
    
    // sevice层
    @Service
    public class UserRedisService {
        @Autowired
        private UserRedisDao userRedisDao;
        @Autowired
        private RedisTemplate redisTemplate;
    
        // 清除缓存
        @CacheEvict(value = "redisCache", allEntries = true)
        public void addUser(User user) {
            userRedisDao.addUser(user);
        }
    
        // 缓存查询
        @Cacheable(value = "redisCache", key = "#age")
        public List<User> selectAge(int age) {
            return userRedisDao.selectAge(age);
        }
    
        // 双重检测锁
        public int selectCount() {
            // 获取redis对象
            BoundValueOperations ops = redisTemplate.boundValueOps("count");
            // 获取值
            Object count = ops.get();
            System.out.println("redis:" + count);
            // 双重检测
            if (ObjectUtils.isEmpty(count)){
                //查询数据库
                count = userRedisDao.selectCount();
                System.out.println("数据库:" + count);
                //设置缓存的过期时效
                ops.set(count, 100, TimeUnit.SECONDS);
            }
            return userRedisDao.selectCount();
        }
    }
    
    
    // dao层
    @Mapper
    public interface UserRedisDao {
    
        void addUser(@Param("param") User user);
    
        List<User> selectAge(int age);
    
        int selectCount();
    }
    
    // xlm文件
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.monkey.springboot.dao.UserRedisDao">
    
        <insert id="addUser">
            insert into user(name, age)
            values (#{param.name}, #{param.age})
        </insert>
        <select id="selectAge" resultType="com.monkey.springboot.entity.User">
            select id,name,age from user
            where age &lt;= #{age}
        </select>
        <select id="selectCount" resultType="java.lang.Integer">
            select count(*) from user
        </select>
    </mapper>
    
            
    // 实体类
    @Data
    public class User implements Serializable {		//必须序列化
        private String id;
        private String name;
        private int age;
    }
    
    
    //index.jsp
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <meta charset="utf-8">
        <title>测试标题</title>
    </head>
    <body>
    <%--redis测试--%>
        <form action="redis/addUser" method="post">
            年龄:<input type="text" name="age"><br>
            姓名:<input type="text" name="name"><br>
            <input type="submit" value="添加用户">
        </form>
        <hr>
        <form action="redis/selectAge" method="post">
            输入最大年龄:<input type="text" name="age"><br>
            <input type="submit" value="查询信息">
        </form>
        <hr>
        <a href="redis/selectCount">查询总人数</a>
    </body>
    </html>
      
        
    // userRedis.jsp
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>添加用户</title>
    </head>
    <body>
        student=${user}<br>
        selectAge = ${userList}<br>
        count = ${count}<br>
    </body>
    </html>
    

4)redis高并发问题

  • 缓存穿透:

    问题:查询结果经常为空,需要访问数据库
    解决:当null时,设置一个默认值,存入缓存
    
  • 缓存雪崩:

    问题:大量缓存同时到期,需要同时更新
    解决:提前规划好缓存到期时间
    
  • 热点缓存:

    问题:某个缓存到期,同时大量访问
    解决:双重检查锁机制
    

5)简单过程

  • 在pom 中添加Redis 与Spring Boot 整合依赖
  • 在配置文件中注册Redis 连接信息
  • 实体类实现序列化接口
  • 在启动类上添加@EnableCaching (没必须,其他依赖中可能包含该注解)
  • 在查询方法上添加@Cacheble,在增删改方法上添加@CacheEvict 【注解实现】
  • 若使用API 方式操作Redis,则需要注入RedisTemplate,然后通过RedisTemplate 获取到Redis 操作对象后就可以对Redis 进行操作了。【双重检查锁机制】

6)redis五大数据类型

  • Redis字符串(String

    String是redis最基本的类型,你可以理解成与Memcached一样的类型,一个key对应一个value。
    
    方法: set 设置值,get获取值,del删除值
    
  • Redis列表(List

    Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部或者尾部。它的底层是一个链表
    
  • Redis集合(Set

    Redis的Set的histring类型的无序集合。他是通过HashTable实现的。
    
  • Redis哈希(Hash

    Redis hash是一个键值对集合。Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
    
    类似Java里面Map<String, Object>
    
  • Redis有序集合Zset(sorted set)

    Redis zset和set一样也是string类型元素的集合,而且不允许重复的成员。
    
    不同的是每个元素都会关联一个double类型的分数。
    
    redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。
    

7)注解@Cacheable和@CacheEvict

  • @Cacheable属性,一般用于查询

    # 属性
    1. value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。
    
    2. key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。
    	自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。下面是几个使用参数作为key的示例。
    	#root.methodName获取方法名称
    
    3. condition属性指定发生的条件
    例如:@Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")
    当id为偶数生效
    
  • @CacheEvict,一般用于增删改

    # 属性
    1. allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。
    当指定了allEntries为true时,Spring Cache将忽略指定的key。
    有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。
    
    2. beforeInvocation属性
       清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。
       使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。
    

2.10 Spring Boot 中Dubbo 的整合应用

  • 后续补

2.11 Spring Boot 下使用拦截器(Token)

​ 在非Spring Boot 工程中若要使用SpringMVC 的拦截器,在定义好拦截器后,需要在Spring配置文件中对其进行注册。但Spring Boot 工程中没有了Spring 配置文件,那么如何使用拦截器呢?
​ Spring Boot 对于原来在配置文件配置的内容,现在全部体现在一个类中,该类需要继承自WebMvcConfigurationSupport 类,并使用**@Configuration 进行注解**,表示该类为一个JavaConfig 类,其充当配置文件的角色

1)步骤

  • 定义拦截器

    public class DefineInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("拦截请求" + request.getRequestURI());
            return true;
        }
    }
    
  • 定义WebMvc 配置类,其需要继承自WebMvcConfigurationSupport,且需要使用@Configuration 进行注解

    @Configuration
    public class IntercptorConfig extends WebMvcConfigurationSupport {
        @Override
        protected void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new DefineInterceptor())
    //                .addPathPatterns("/first/**");  //拦截first开头的url
                    .excludePathPatterns("/first/**");      //拦截除first开图的url
        }
    }
    
  • controller类,无需修改主配置文件

@RestController
public class InterceptorController {

    @GetMapping("/first/request")
    public String first(){
        return "first request";
    }

    @GetMapping("/second/request")
    public String second(){
        return "second request";
    }

    @GetMapping("/third/request")
    public String third(){
        return "third request";
    }

2.12 Spring Boot 中使用Servlet

在Spring Boot 中使用Servlet,根据Servlet 注册方式的不同,有两种使用方式。

  • 若使用的是Servlet3.0+版本,则两种方式均可使用;
  • 若使用的是Servlet2.5 版本,则只能使用配置类方式。

2.13 Spring Boot 中使用Filter

在Spring Boot 中使用Filter 与前面的使用Servlet 相似,根据Filter 注册方式的不同,有两种使用方式。

  • 若使用的是Servlet3.0+版本,则两种方式均可使用;
  • 若使用的是Servlet2.5版本,则只能使用配置类方式

补充: 整合myabtis-plus

第3章 模板引擎Thymeleaf

3.1 Thymeleaf 简介

​ Thymeleaf[taɪm lif],百里香叶,是一个流行的模板引擎,该模板引擎采用Java 语言开发。
Java 中常见的模板引擎有Velocity、Freemaker、Thymeleaf 等。不同的模板引擎都会具有自
己的特定的标签体系,而Thymeleaf 以HTML 标签为载体,在HTML 的标签下实现对数据的
展示。

​ Thymeleaf 本身与SpringBoot 是没有关系的,但SpringBoot 官方推荐使用Thymeleaf 作
为前端页面的数据展示技术,SpringBoot 很好地集成了这种模板技术。
​ Thymeleaf 的官网为: http://www.thymeleaf.org

3.2 Spring Boot 集成Thymeleaf

  • 导入如下依赖

    <!--Thymeleaf-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    
  • controller类

    @Controller
    public class ThymeleafController {
    
        @GetMapping("/thymeleaf")
        public String thymeleaf(Model model){
            model.addAttribute("test", "hello world!");
            //显示html页面,不用写后缀名
            return "index";
        }
    }
    
  • index.html文件(必须在resource/template下创建html)

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <p th:text="${test}">显示test值</p>
        <div th:text="${test}">显示test值</div>
        <span th:text="${test}">显示test值</span>
    
    </body>
    </html>
    
  • yaml配置文件(建议关闭缓存)

      # 建议关闭缓存,否则可能会出现数据未更新情况
      spring:
      	thymeleaf:
        	cache: false
    

3.3 Thymeleaf 标准表达式

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--    变量表达式${...} -->
    <p th:text="${student}">显示test值</p>
    <p th:text="${student.name}">显示test值</p>
    <p th:text="${student.age}">显示test值</p>
<hr>
<!--    选择表达式*{...} -->
    <div th:object="${student}">
        <p th:text="*{name}">显示test值</p>
        <p th:text="*{age}">显示test值</p>
    </div>
<hr>
<!--    URL 表达式@{...} -->
    <a th:href="@{'http://localhost:8080/thymeleaf1/' + ${student.name}}">跳转1</a><br>
    <a th:href="@{|http://localhost:8080/thymeleaf1/${student.name}|}">跳转2</a><br>
    <a th:href="@{|/thymeleaf1/${student.name}|}">跳转3</a>

</body>
</html>

3.4 Thymeleaf 常见属性

1)th:if 或th:switch/th:case

该属性用于逻辑判断,类似于JSTL 中的<c:if/>。

2)th:each

该属性用于遍历数组、List、Set、Map,类似于JSTL 中的<c:forEach/>。

3)th:text/th:utext

1. th:utext 会解析文本中的HTML 标签,
2. th:text 则是原样显示。

4)th:id/th:name

这两个属性可以获取标签的动态id 与name 属性,以便在js 中使用。

5)th:style

该属性用于获取标签的css 动态样式。

6)th:onclick

该属性用于获取标签的单击事件所触发的动态事件,即单击事件所触发的方法名。这些js 事件属性很多,都是以th:on 开头。

7)内联属性th:inline

1. 其应用场景是,在HTML 某标签显示文本内部存在部分数据来自于动态数据,或JS 内部需要使用动态数据的场景。在该场景中,可以使用[[${...}]]或[(${...})]的方式将动态数据嵌入到指定的文本或脚本内部。 

2. th:inline 的取值有四个:text, javascript、css  和  non。分别表示内联文本、内联脚本、内联css,与禁止内联,即不解析[[${...}]]。不过,th:inline=”text”可以省略不写。

8)万能属性th:attr

很多HTML 标签的属性都有其对应的Thymeleaf 的th 命名空间中属性,但并不是所有的都存在对应属性。若没有其对应的th 命名空属性,但又想让其获取动态值,就需要使用该属性了

3.5 Thymeleaf 运算基础

字面量,即字面常量。Thymeleaf 中有四种字面量:文本、数字、布尔,及null。

第4章 Spring Boot 源码解析

4.1 自动配置源码解析

1)解析@SpringBootApplication

  • 前四个是专门(即只能)用于对注解进行注解的,称为元注解。

    1.@Target(ElementType.TYPE)  //Target注解可以修饰,如果注解超出了注解的修饰范围就会报错
        TYPE,             // 类,接口,枚举声明
    	FIELD,            // 枚举值
    	METHOD,           // 方法
    	PARAMETER,        // 形参
    	CONSTRUCTOR,      // 构造器
        LOCAL_VARIABLE,   // 局部变量
        ANNOTATION_TYPE,  // 注解
        PACKAGE,          // 包
    2.@Retention(RetentionPolicy.RUNTIME)  
        @Retention(RetentionPolicy.RUNTIME) // 注解保留位置
    	@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码文件中不包含
        @Retention(RetentionPolicy.CLASS) //默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
        @Retention(RetentionPolicy.RUNTIOME) //注解会在class字节码文件中存在,在运行时可以通过反射获取到
    
    3.@Documented  //avadoc工具会将此注解标记元素的注解信息包含在javadoc中。默认,注解信息不会包含在Javadoc中
    4.@Inherited //表示注解会被自动继承。
    

2) @SpringBootConfiguration

  • 查看该注解的源码注解可知,该注解与@Configuration 注解功能相同,仅表示当前类为一个JavaConfig 类,其就是为Spring Boot 专门创建的一个注解。

3) @ComponentScan

  • 顾名思义,用于完成组件扫描。不过需要注意,其仅仅是指定了要扫描的包,并没有装配其中的类,这个真正装配这些类是**@EnableAutoConfiguration** 完成的。

4) @EnableAutoConfiguration

​ @EnableXxx 注解一般用于开启某一项功能,是为了简化代码的导入。其是组合注解,一般情况下@EnableXxx 注解中都会组合一个**@Import** 注解,而该@Import 注解用于导入指定的类,而被导入的类一般有三种:

  • A、 配置类
    @Import 中指定的类一般为Configuration 结尾,且该类上会注解@Configuration,表示当前类为JavaConfig 类。

  • B、 选择器
    @Import 中指定的类一般以Selector 结尾,且该类实现了ImportSelector 接口,表示当前类会根据条件选择导入不同的类。

  • C、 注册器
    @Import 中指定的类一般以Registrar 结尾,且该类实现了ImportBeanDefinitionRegistrar接口,用于导入注册器,该类可以在代码运行时动态注册指定类的实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值