天天看點

SpringBoot 學習筆記

常用注解

主程式類:@SpringBootApplication

等同 @SpringBootConfiguration  @EnableAutoConfiguration  @ComponentScan("com.atguigu.boot")

/* 主程式類
 * @SpringBootApplication:這是一個SpringBoot應用*/
@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class,args);
    }
}      

控制器:@RestController

@RequestMapping("/hello")

@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String handle01(){
        return "Hello, Spring Boot 2!";
    }
}      

配置類:@Configuration

告訴SpringBoot這是一個配置類 == 配置檔案

參數 proxyBeanMethods

=false 傳回新的執行個體 配置類元件之間無依賴關系用Lite模式加速容器啟動過程,減少判斷

=ture  單執行個體,是預設值,配置類元件之間有依賴關系,方法會被調用得到之前單執行個體元件,元件依賴必須使用用Full模式

添加元件:@Bean

給容器中添加元件,元件id為方法名

@Bean("componentName")

@Configuration(proxyBeanMethods = false)
public class MyConfig {
    @Bean //給容器中添加元件。以方法名作為元件的id。傳回類型就是元件類型。傳回的值,就是元件在容器中的執行個體
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        //user元件依賴了Pet元件
        zhangsan.setPet(tomcatPet());
        return zhangsan;
    }


################################@Configuration測試代碼如下########################################
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.atguigu.boot")
public class MainApplication {

    public static void main(String[] args) {
        //1、傳回我們IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //2、檢視容器裡面的元件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }

        //3、從容器中擷取元件

        Pet tom01 = run.getBean("tom", Pet.class);
        Pet tom02 = run.getBean("tom", Pet.class);
        System.out.println("元件:"+(tom01 == tom02));

        //4、com.atguigu.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892
        MyConfig bean = run.getBean(MyConfig.class);
        System.out.println(bean);

        //如果@Configuration(proxyBeanMethods = true)代理對象調用方法。SpringBoot總會檢查這個元件是否在容器中有。
        //保持元件單執行個體
        User user = bean.user01();
        User user1 = bean.user01();
        System.out.println(user == user1);


        User user01 = run.getBean("user01", User.class);
        Pet tom = run.getBean("tom", Pet.class);

        System.out.println("使用者的寵物:"+(user01.getPet() == tom));

    }
}      

自動建立元件:@Import

給容器中自動建立出這兩個類型的元件、預設元件的名字就是全類名

@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false) //告訴SpringBoot這是一個配置類 == 配置檔案
public class MyConfig {
}      

條件配置:@Conditionalxxx

@Configuration(proxyBeanMethods = false) //告訴SpringBoot這是一個配置類 == 配置檔案
//@ConditionalOnBean(name = "tom")
@ConditionalOnMissingBean(name = "tom")
public class MyConfig {


    /**
     * Full:外部無論對配置類中的這個元件注冊方法調用多少次擷取的都是之前注冊容器中的單執行個體對象
     * @return
     */

    @Bean //給容器中添加元件。以方法名作為元件的id。傳回類型就是元件類型。傳回的值,就是元件在容器中的執行個體
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        //user元件依賴了Pet元件
        zhangsan.setPet(tomcatPet());
        return zhangsan;
    }

    @Bean("tom22")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}

public static void main(String[] args) {
        //1、傳回我們IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //2、檢視容器裡面的元件
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }

        boolean tom = run.containsBean("tom");
        System.out.println("容器中Tom元件:"+tom);

        boolean user01 = run.containsBean("user01");
        System.out.println("容器中user01元件:"+user01);

        boolean tom22 = run.containsBean("tom22");
        System.out.println("容器中tom22元件:"+tom22);


    }      

原生配置引入:@ImportResource

@ImportResource("classpath:beans.xml")
public class MyConfig {}

======================測試=================
        boolean haha = run.containsBean("haha");
        boolean hehe = run.containsBean("hehe");
        System.out.println("haha:"+haha);//true
        System.out.println("hehe:"+hehe);//true      

掃描位置:@ComponentScan

配置綁定 :@ConfigurationProperties

原始寫法:

public class getProperties {
     public static void main(String[] args) throws FileNotFoundException, IOException {
         Properties pps = new Properties();
         pps.load(new FileInputStream("a.properties"));
         Enumeration enum1 = pps.propertyNames();//得到配置檔案的名字
         while(enum1.hasMoreElements()) {
             String strKey = (String) enum1.nextElement();
             String strValue = pps.getProperty(strKey);
             System.out.println(strKey + "=" + strValue);
             //封裝到JavaBean。
         }
     }
 }      
/**
 * 隻有在容器中的元件,才會擁有SpringBoot提供的強大功能
 */
@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {
    private String brand;
    private Integer price;
}      

yaml寫法

@Component
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "user")
public class User {
    private String username;
    private int age;
    private Pet pet;
    private List<Pet> pets;
    private String[] courses;
}      
user:
  age: 12
  pet:
    name: ap
    age: 3
  pets:
    - {name: bp, age: 4}
    - {name: cp, age: 5}
  courses: ['math', 'chinese', 'english']
  username: Jack

server:
  port: 8081      

配置提示和優化

<!--配置提示-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

<plugin> 
  <groupId>org.springframework.boot</groupId>  
  <artifactId>spring-boot-maven-plugin</artifactId>  
  <configuration> 
    <excludes> 
      <!--打包時排除配置的提示,優化JVM啟動-->  
      <exclude> 
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-configuration-processor</artifactId> 
      </exclude> 
    </excludes> 
  </configuration> 
</plugin>      

配置連接配接池

方案1 java 代碼注入

jdbc.properties

jdbc.driver: com.mysql.jdbc.Driver
jdbc.url: jdbc:mysql://192.168.31.133:3306/boot
jdbc.username: jack
jdbc.password: jack      

配置類

@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
    @Value("${jdbc.driver}")
    private String driver;
    @Value("${jdbc.url}")
    private String url;
    @Value("${jdbc.username}")
    private String username;
    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

}      

注入 controller

    @Autowired
    private DataSource dataSource;      

方案2 屬性注入

@Bean
@ConfigurationProperties(prefix = "jdbc")
public DataSource dataSource() {
    return new DruidDataSource();
}      

application.properties

jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.31.133:3306/mybatis
jdbc.username=jack
jdbc.password=jack      

靜态資源通路

隻要靜态資源放在類路徑下: /static (or  /publicor/resourcesor/META-INF/resources`

通路 : 目前項目根路徑/ + 靜态資源名

改變預設的靜态資源路徑

spring:
  mvc:
    static-path-pattern: /res/**

  resources:
    static-locations: [classpath:/haha/]      

靜态資源通路字首

 預設:/**
  web:
    resources:
      static-locations: [classpath:/haha]      

webjar 自動映射

https://www.webjars.org/

通路位址:http://localhost:8080/webjars/jquery/3.5.1/jquery.js  後面位址要按照依賴裡面的包路徑

YML 配置檔案

application.yml

jdbc:
  driverClassName: com.mysql.cj.jdbc.Driver
  url: jdbc:mysql://192.168.31.133/boot
  username: jack
  password: jack


spring:
  profiles:
    active:
      1      

配置多個 yml 檔案

application-1.yml

user:
  name: "楊青林"
  email: [email protected]      

配置日志

需要輸出日志的類上添加注解 @Slf4j

@Slf4j
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.debug("MyInterceptor ----  preHandle");
        return true;
    }
}      
logging:
  level:
    cn.lin: debug
    org.spring: info      

配置攔截器

編寫攔截器類

@Slf4j
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, 
    	HttpServletResponse response, Object handler) throws Exception {
    	
        log.debug("MyInterceptor ----  preHandle");
        return true;
    }
}      

springmvc配置類

@Configuration
public class SpringmvcConfig implements WebMvcConfigurer {

    // 注冊攔截器到 Spring IOC 容器中
    @Bean
    public MyInterceptor myInterceptor() {
        return new MyInterceptor();
    }

    // 将攔截器添加到攔截器鍊
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor());
    }
}      

整合mybatis

事務配置

添加依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>      

添加注解

@Transactional

配置Hikari連接配接池

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>      

配置 application.yml

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://192.168.31.133/springboot_test
    username: jack
    password: jack      

添加mybatis場景啟動器

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.4</version>
</dependency>      

mybatis

編寫application.yml

mybatis:
  #  實體類别名路徑
  type-aliases-package: cn.lin.pojo
  #  映射檔案目錄
  #  mapper-locations:
  configuration:
    #  控制台輸出 sql
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl      

掃描mybatis的mapper接口

  • 啟動類中添加注解 @MapperScan (推薦)
  • 在Mapper接口中添加注解 @Mapper

整合通用Mapper

<dependency>
    <groupId>tk.mybatis</groupId>
    <artifactId>mapper-spring-boot-starter</artifactId>
    <version>2.1.5</version>
</dependency>      

編寫實體類

@Data
@Table(name = "tb_user")
public class User {
    @Id
    @KeySql(useGeneratedKeys = true)
    private Long id;
    private String user_name;
    private String password;
    private String name;
    private Integer age;
    private Short sex;
    private Date birthday;
    private String note;
    private Date created;
    private Date updated;
}      

配置包掃描

@SpringBootApplication
@MapperScan("cn.lin.mapper")
public class Application {}      

測試代碼

@GetMapping("/{id}")
public User queryById(@PathVariable Long id) {
    log.debug("queryById");
    return userService.queryByID(id);
}


@Transactional
public User queryByID(Long id) {
    return userMapper.selectByPrimaryKey(id);
}      

整合redis

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>      

配置application.yml

spring:
  redis:
    host: 192.168.31.133
    port: 6379      
public class RedisTest {

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void test(){
        //string 字元串
        //redisTemplate.opsForValue().set("str", "heima");
        redisTemplate.boundValueOps("str").set("heima");
        System.out.println("str = " + redisTemplate.opsForValue().get("str"));

        //hash 散列
        redisTemplate.boundHashOps("h_key").put("name", "heima");
        redisTemplate.boundHashOps("h_key").put("age", 13);
        //擷取所有域
        Set set = redisTemplate.boundHashOps("h_key").keys();
        System.out.println(" hash散列的所有域:" + set);
        //擷取所有值
        List list = redisTemplate.boundHashOps("h_key").values();
        System.out.println(" hash散列的所有域的值:" + list);

        //list 清單
        redisTemplate.boundListOps("l_key").leftPush("c");
        redisTemplate.boundListOps("l_key").leftPush("b");
        redisTemplate.boundListOps("l_key").leftPush("a");
        //擷取全部元素
        list = redisTemplate.boundListOps("l_key").range(0, -1);
        System.out.println(" list清單中的所有元素:" + list);

        // set 集合
        redisTemplate.boundSetOps("s_key").add("a", "b", "c");
        set = redisTemplate.boundSetOps("s_key").members();
        System.out.println(" set集合中的所有元素:" + set);

        // sorted set 有序集合
        redisTemplate.boundZSetOps("z_key").add("a", 30);
        redisTemplate.boundZSetOps("z_key").add("b", 20);
        redisTemplate.boundZSetOps("z_key").add("c", 10);
        set = redisTemplate.boundZSetOps("z_key").range(0, -1);
        System.out.println(" zset有序集合中的所有元素:" + set);
    }
}      

簡化開發

Lombok

<!--簡化JavaBean開發-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>      

dev-tools

<!--Ctrl+F9重新整理項目-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
</dependency>      

log4j

<?xml version="1.0" encoding="UTF-8"?>
<!--日志級别以及優先級排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE >
ALL -->
<!--Configuration 後面的 status 用于設定 log4j2 自身内部的資訊輸出,可以不設定,
當設定成 trace 時,可以看到 log4j2 内部各種詳細輸出-->
<configuration status="INFO">
    <!--先定義所有的 appender-->
    <appenders>
        <!--輸出日志資訊到控制台-->
        <console name="Console" target="SYSTEM_OUT">
            <!--控制日志輸出的格式-->
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-
5level %logger{36} - %msg%n"/>
        </console>
    </appenders>
    <!--然後定義 logger,隻有定義 logger 并引入的 appender,appender 才會生效-->
    <!--root:用于指定項目的根日志,如果沒有單獨指定 Logger,則會使用 root 作為
    預設的日志輸出-->
    <loggers>
        <root level="info">
            <appender-ref ref="Console"/>
        </root>
    </loggers>
</configuration>      

繼續閱讀