SpringBoot学习记录

154 阅读7分钟

SpringBoot加载bean的几种方式

方式一:直接从配置文件中获取

1、配置文件

<?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="book" class="com.boot.stu.bean.Book">
        <property name="bookName" value="三体"></property>
        <property name="author" value="留心此"></property>
    </bean>
</beans>

2、加载方式

public class Applicaiton01 {

    public static void main(String[] args) {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("springconfig.xml");
        Book bean = ioc.getBean(Book.class);
        System.out.println(bean);
    }
}

方式二:通过一些注解进行架子啊

controller、service、component 等等。。

1、写配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


   <context:component-scan base-package="com.boot.stu"></context:component-scan>
</beans>

2、加载方式

public class Applicaiton02 {
    public static void main(String[] args) {
        ApplicationContext ioc = new ClassPathXmlApplicationContext("springconfig02.xml");
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String strName:beanDefinitionNames){
            System.out.println(strName);
        }
        Cat bean = ioc.getBean(Cat.class);
        System.out.println(bean);
    }
}

方式三:不用xml的配置文件进行加载

1、写一个配置类

@ComponentScan(value = "com.boot.stu")
public class AppConfig {
}

2、加载方式

public class Applicaiton03 {
    public static void main(String[] args) {
        ApplicationContext ioc = new AnnotationConfigApplicationContext(AppConfig.class);
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String strName:beanDefinitionNames){
            System.out.println(strName);
        }
        Cat bean = ioc.getBean(Cat.class);
        System.out.println(bean);
    }
}

方式四、通过工程类加载

1、写一个工厂类

public class MyFactory implements FactoryBean<Book> {
    @Override
    public Book getObject() throws Exception {
        Book book = new Book();
        book.setBookName("love");
        book.setAuthor("love love");
        return book;
    }

    @Override
    public Class<?> getObjectType() {
        return Book.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

2、将工厂加载进来

image.png

3、加载方式

public class Applicaiton04 {
    public static void main(String[] args) throws Exception {
        ApplicationContext ioc = new AnnotationConfigApplicationContext(AppConfig.class);
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String strName:beanDefinitionNames){
            System.out.println(strName);
        }
        FactoryBean bean = ioc.getBean(FactoryBean.class);
        Object object = bean.getObject();
        System.out.println(object);
    }
}

方式五:加载配置类并加载配置文件(系统迁移)

1、写一个配置类

@ComponentScan("com.boot.stu")
@ImportResource("springconfig.xml")
public class AppConfig02 {
}

2、加载方式

public class Applicaiton05 {
    public static void main(String[] args) throws Exception {
        ApplicationContext ioc = new AnnotationConfigApplicationContext(AppConfig02.class);
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String strName:beanDefinitionNames){
            System.out.println(strName);
        }
    }
}

@Configuration 注解

image.png

方式六:通过Import注解

1、创建配置类

@Import(Dog.class)
public class AppConfig03 {
}

2、加载方式

@Configuration
public class Applicaiton06 {
    public static void main(String[] args) throws Exception {
        ApplicationContext ioc = new AnnotationConfigApplicationContext(AppConfig03.class);
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String strName:beanDefinitionNames){
            System.out.println(strName);
        }
    }
}

方式七:使用上下文对象在容器初始化完毕后注入bean

1、写配置类

@Import(Dog.class)
public class AppConfig03 {
}

2、加载方式

public class Applicaiton07 {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(AppConfig03.class);
        ioc.register(Book.class);
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String strName:beanDefinitionNames){
            System.out.println(strName);
        }
    }
}

方式八 导入实现了ImportSelector接口的类,实现对导入源的编程式处理

1、写一个importSelector

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.boot.stu.bean.Book","com.boot.stu.bean.Dog"};
    }
}

2、写一个配置类

@Import(MyImportSelector.class)
public class AppConfig04 {
}

3、加载Bena

public class Applicaiton08 {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(AppConfig04.class);
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String strName:beanDefinitionNames){
            System.out.println(strName);
        }
    }
}

方式九 通过ImportBeanDefinitionRegistrar

1、实现ImportBeanDefinitionRegistrar

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Dog.class).getBeanDefinition();
        registry.registerBeanDefinition("xiaoheihei",beanDefinition);
    }
}

2、做配置类

@Import(MyImportBeanDefinitionRegistrar.class)
public class AppConfig05 {
}

3、加载Bean

public class Applicaiton09 {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(AppConfig05.class);
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String strName:beanDefinitionNames){
            System.out.println(strName);
        }
    }
}

方式十:通过 BeanDefinitionRegistryPostProcessor

1、实现BeanDefinitionRegistryPostProcessor方法

public class MyPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        BeanDefinition beanDefinition = BeanDefinitionBuilder
                .rootBeanDefinition(Dog.class)
                .getBeanDefinition();
        beanDefinitionRegistry.registerBeanDefinition("zhangxiaohei", beanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}

2、写配置类

@Import(MyPostProcessor.class)
public class AppConfig06 {
}

3、加载Bean

public class Applicaiton10 {
    public static void main(String[] args) throws Exception {
        AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(AppConfig06.class);
        String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
        for (String strName:beanDefinitionNames){
            System.out.println(strName);
        }
    }
}

基础应用

环境快速搭建

1、创建Maven工程,引入Pom文件

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.0</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

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

2、写启动类

package com.boot.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ApplicationMain {
    public static void main(String[] args) {
        SpringApplication.run(ApplicationMain.class);
    }
}

3、模拟发送一个请求

@RestController
public class BootController {
    @RequestMapping("/hello")
    public String startBoot(){
        return "Hello World";
    }
}

image.png

配置相关

在SpringBoot中的配置文件类型主要有以下三种 以 .properties结尾、.yaml结尾、.yml结尾的。他们的加载顺序依次是application.properties > application.yml > application.yaml

常用的配置需改

# 修改端口
server:
  port: 8088
logging:
# 修改日志级别
#debug、info、error
  level:
    root: debug

配置修改查阅网站:docs.spring.io/spring-boot…

yaml 文件提示失效问题

image.png

image.png

yaml书写格式

  • 1、大小写敏感
  • 2、属性层级关系使用多行描述,每行结尾使用冒号结束
  • 3、使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)
  • 4、使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)
  • 5、# 表示注释
  • 核心规则:数据前面要加空格与冒号隔开
#普通写法
age: 18
name: niuxiaoniu


#一组数据
subject:
  - java
  - 前端
  - 大数据

subject1: ["java","前端","大数据"]

#对象
user1:
  name: zhangsanfeng
  age: 18


#对象集合写法1
user:
  - name: zhangsan
    age: 18
  - name: lisi
    age: 18
#对象集合写法2
user2: [{name: zhangsan,age: 18},{name: lisi,age: 18}]

yaml配置文件的数据读取

使用@Value读取单个数据,属性名引用方式:${一级属性名.二级属性名……}

@Value("name")
String name;

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

//读取所有的数据
@Autowired
Environment environment;

读取一个对象

生成一个User类,这里面的字段信息要和 yaml里面的字段信息对应上

image.png

@Component
@ConfigurationProperties(prefix = "user1")
public class User {
    private String name;
    private Integer age;

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

整合相关的资源

整合测试

在pom文件中添加以下内容

<!--整合测试-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

写测试类

@SpringBootTest
public class ApplicationTest {

![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/15ace0541d24468081b66f49a35cddc2~tplv-k3u1fbpfcp-watermark.image?)
    @Autowired
    private User user;

    @Test
    void contextLoads(){
        System.out.println(user);
    }

}

整合mybatis

1、添加如下的pom文件信息

<!--整合mybatis-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

2、配置数据源

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/jdbctest?serverTimezone=GMT%2B8&characterEncoding=utf8
    username: root
    password: root

3、编写测试类代码

@Mapper
public interface StudentDao {

    @Select("select * from student where stuNo = #{id}")
    public Student getById(Integer id);
}

4、运行测试代码

@SpringBootTest
public class ApplicationTest {
    @Autowired
    private StudentDao studentDao;
    @Test
    void studentTest(){
        Student stu = studentDao.getById(1);
        System.out.println(stu);
    }
}

image.png

整合mybatis-plus

1、添加pom

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.0</version>
</dependency>

2、写配置

server:
  port: 8088
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/jdbctest?serverTimezone=GMT%2B8&characterEncoding=utf8
    username: root
    password: root

# 关闭自动转驼峰
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: false

3、写JavaBean、请自行创建set/get方法

@Data
@TableName("student")
public class Student {
    @TableId()
    private Integer stuNo;
    private String stuName;
    private Integer stuSex;

    @Override
    public String toString() {
        return "Student{" +
                "stuNo=" + stuNo +
                ", stuName='" + stuName + ''' +
                ", stuSex=" + stuSex +
                '}';
    }
}

4、创建Mapper

@Mapper
public interface StudentMapper extends BaseMapper<Student> {

}

5、写测试类

@SpringBootTest
public class ApplicationTest {
    @Autowired
    private StudentMapper studentMapper;

    @Test
    void studentMP(){
        System.out.println(studentMapper.selectById(1));
    }
}

6、执行测试

image.png

运维相关

项目打包

1、项目打包少不了maven插件,首先在springboot01工程中引入maven插件

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

2、跳过测试过程直接点击package打包即可,打包完成以后,会生成相应的Jar文件,在Cmd命令窗口使用 java -jar 包名即可使用。

image.png

3、启动这个包

image.png

命令在启动的时候,端口被占用的解决方案

# 查询端口 netstat -ano 
# 查询指定端口 netstat -ano |findstr "端口号" 
# 根据进程PID查询进程名称 tasklist |findstr "进程PID号" 
# 根据PID杀死任务 taskkill /F /PID "进程PID号" 
# 根据进程名称杀死任务 taskkill -f -t -im "进程名称"

多环境配置

配置在一个yaml文件中

server:
  port: 80

# 应用环境
spring:
  profiles:
    active: dev

# 设置环境
---
# 生产环境
server:
  port: 81
spring:
  profiles: pro

---
# 开发环境
server:
  port: 82
spring:
  profiles: dev

---
# 测试环境
server:
  port: 83
spring:
  profiles: test

多环境拆分

image.png

开发环境

image.png

生产环境

image.png

测试环境

image.png

开发常用

热部署

添加开发者工具

image.png

激活热部署ctrl + F9

避免每一次都手动的build

image.png

然后 同时按下 ctrl + alt + shift + /

image.png

image.png

热部署的范围配置

默认不触发重启的目录列表

/META-INF/maven
/META-INF/resources
/resources
/static
/public
/templates

自定义不参与重启和排除

devtools:
  restart:
    exclude: public/**,static/**

属性绑定

@ConfigurationProperties 做属性绑定

1、创建一个新的springboot工程

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

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

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

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

2、写配置文件

server:
  ipAddress: 192.168.216.140
  port: 8888
  timeout: -1

3、写实体Bean,并赋值

@Component
@Data
@ConfigurationProperties(prefix = "server")
public class SeverConfig {
    private String ipAddress;
    private String port;
    private String timeout;
}

4、启动测试

@SpringBootApplication
public class ApplicationMain {
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(ApplicationMain.class);
        SeverConfig bean = run.getBean(SeverConfig.class);
        System.out.println(bean);
    }
}

image.png

为第三方的组件绑定属性

1、添加第三方的pom

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.16</version>
</dependency>

2、写配置文件

image.png

3、测试 image.png

使用@EnableConfigurationProperties(SeverConfig.class)这个注解可以将使用@ConfigurationProperties(prefix = "server")注解对应的类加入到Spring容器

image.png

属性校验

1、添加属性校验的POM

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
</dependency>

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
</dependency>

2、为Bean开启数据校验

使用 @Validated 开启数据校验功能

image.png