Spring Boot-001-之初学

142 阅读4分钟

前言:之前和一些视频学习 Spring Boot 但都是默认 Spring 和 Spring MVC 的基础,之前也尝试从头搞起,但感觉太慢,我想快速上手,于是又和书开始学。杂糅一起来吧

Spring Boot 的优点

创建独立的 Spring应用程序;
嵌入的 Tomcat、 Jetty 或者 Undertow,无须部署 WAR 文件:
允许通过 Maven 来根据 需要获 取 starter;
尽可能地自动配置 Spring;
提供生 产 就绪型功能,如指标、健康检查和外部配置;
绝对没有代码生成,对 XML 没有要求配置 。

Spring Boot注解

@Configuration代表这是一个Java配置文件,Spring容器会根据它来生成IoC容器去装配Bean,@Bean代表方法返回的POJO装配到容器中name属性定义这个 Bean 的名称告诉Spring Boot这是一个配置类 == 配置文件
配置类本身也是组件
配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单例的
@Configuration(proxyBeanMethods = false) 代理Bean的方法
Full:proxyBeanMethods = true
Lite:proxyBeanMethods = false
组件依赖检查,检查组件里面是否依赖了别的组件
默认是开启
一般情况下,如果组件有互相依赖,使用proxyBeanMethods = true,没有依赖使用false
写法如下

package org.greenfred.springboot.demos.base01;  
  
import org.greenfred.springboot.demos.base01.bean.User;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
  
@Configuration  
public class Base01 {  
    @Bean(name = "user")  
    public User initUser() {  
        User user = new User();  
        user.setId(1);  
        user.setName("张三");  
        user.setAge(18);  
        return user;  
    }  
}

package org.greenfred.springboot.demos.base01.bean;  
  
public class User {  
    private int id;  
    private String name;  
    private int age;  
  
    @Override  
    public String toString() {  
        return "User{" +  
                "id=" + id +  
                ", name='" + name + '\'' +  
                ", age=" + age +  
                '}';  
    }  
  
    public User(int id, String name, int age) {  
        this.id = id;  
        this.name = name;  
        this.age = age;  
    }  
  
    public User() {  
    }  
  
    public int getId() {  
        return id;  
    }  
  
    public void setId(int id) {  
        this.id = id;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public int getAge() {  
        return age;  
    }  
  
    public void setAge(int age) {  
        this.age = age;  
    }  
}

之后可通过注解上下文获取Bean

package org.greenfred.springboot;  
  
import org.greenfred.springboot.demos.base01.Base01;  
import org.greenfred.springboot.demos.base01.bean.User;  
import org.junit.jupiter.api.Test;  
import org.springframework.boot.test.context.SpringBootTest;  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.annotation.AnnotationConfigApplicationContext;  
  
@SpringBootTest  
class ApplicationTests {  
  
    @Test  
    void contextLoads() {  
        ApplicationContext context = new AnnotationConfigApplicationContext(Base01.class);  
        User user = context.getBean(User.class);  
        System.out.println(user);  
    }  
  
}

打印结果 Pasted image 20241020094855.png

通过扫描装配Bean

@Component和@ComponentScan
@Component表明哪个类被扫描进入 Spring IoC容器中
@ComponentScan 则是标明采用何种策略去扫描装配 Beano
改造后的Bean

package org.greenfred.springboot.demos.base01.bean;  
  
import org.springframework.beans.factory.annotation.Value;  
import org.springframework.stereotype.Component;  
  
@Component("user")  
public class User {  
    @Value("2")  
    private int id;  
    @Value("李四")  
    private String name;  
    @Value("19")  
    private int age;  
  
    @Override  
    public String toString() {  
        return "User{" +  
                "id=" + id +  
                ", name='" + name + '\'' +  
                ", age=" + age +  
                '}';  
    }  
  
    public User(int id, String name, int age) {  
        this.id = id;  
        this.name = name;  
        this.age = age;  
    }  
  
    public User() {  
    }  
  
    public int getId() {  
        return id;  
    }  
  
    public void setId(int id) {  
        this.id = id;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public int getAge() {  
        return age;  
    }  
  
    public void setAge(int age) {  
        this.age = age;  
    }  
}

改造后的base

package org.greenfred.springboot.demos.base01;  
  
  
import org.springframework.context.annotation.ComponentScan;  
  
import org.springframework.context.annotation.Configuration;  
  
@Configuration  
@ComponentScan  
public class Base01 {  
  
}

打印结果 Pasted image 20241020100029.png

@Autowired 很重要

它会根据属性的类型(bytype)找到对应的 Bean进行注入

package org.greenfred.springboot.demos.base02.interfaces;  
  
public interface Person {  
    //使用动物服务  
    public void service() ;  
    //设置动物  
    public void setAnimal(Animal animal) ;  
}

package org.greenfred.springboot.demos.base02.interfaces;  
  
public interface Animal {  
    public void use();  
}

package org.greenfred.springboot.demos.base02.impl;  
  
  
import org.greenfred.springboot.demos.base02.interfaces.Animal;  
import org.greenfred.springboot.demos.base02.interfaces.Person;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.context.annotation.ComponentScan;  
import org.springframework.context.annotation.Configuration;  
  
  
@ComponentScan  
@Configuration
public class PersonImpl implements Person {  
  
    @Autowired  
    private Animal animal = null;  
  
    @Override  
    public void service() {  
        this.animal.use();  
    }  
  
    @Override  
    public void setAnimal(Animal animal) {  
        this.animal = animal;  
    }  
}


package org.greenfred.springboot.demos.base02.impl;  
  
import org.greenfred.springboot.demos.base02.interfaces.Animal;  
import org.springframework.stereotype.Component;  
  
@Component  
public class Cat implements Animal {  
    @Override  
    public void use() {  
        System.out.println("这是猫");  
    }  
}

打印结果

Pasted image 20241022091919.png
如果再增加狗类 Pasted image 20241022092859.png 则会出现找到两个Bean的问题 Pasted image 20241022092950.png @Autowired提供了这样的规则:首先根据类型类型找对应的Bean
此时修改@Autowired修饰的属性修改为狗即可
Pasted image 20241022093217.png Pasted image 20241022093349.png 消除歧义性 @ Primary 和 @ Quelifier
@ Primary:它是一个修改优先权的注解,在cat标注后如果同时有多个Bean,使用@Primary 修饰的

@Primary  
public class Cat implements Animal {  
    @Override  
    public void use() {  
        System.out.println("这是猫");  
    }  
}

打印结果 Pasted image 20241022110358.png @Qualifier("") 可以指定要注入哪个Bean

@ComponentScan  
@Configuration  
public class PersonImpl implements Person {  
  
    @Autowired  
    @Qualifier("dog")  
    private Animal animal = null;  
  
    @Override  
    public void service() {  
        this.animal.use();  
    }  
  
    @Override  
    public void setAnimal(Animal animal) {  
        this.animal = animal;  
    }  
}

@Component  
@Primary  
public class Cat implements Animal {  
    @Override  
    public void use() {  
        System.out.println("这是猫");  
    }  
}

当设置 @Qualifier("") 之后会注入指定的Bean,优先级会大于 @Primary
打印结果 Pasted image 20241022152030.png

以下是和视频学遇到的坑,希望能帮大家规避

Pasted image 20240904153442.png


# 服务端口  
server.port=8080  
# Springlogo图  
spring.main.banner-mode=off

配置文件优先级 properties > yml > yaml

Pasted image 20240904160416.png

上手

@SpringBootApplication
表示这是一个Spring Boot应用程序
是主程序类,入口

编写一个Controller


@Controller  
public class HelloSpringBoot {  
    @RequestMapping("/hello")  
    @ResponseBody  
    public String helloSpringBoot() {  
        return "欢迎使用SpringBoot";  
    }  
  
    public HelloSpringBoot() {  
    }  
}

Pasted image 20240903102226.png Spring Boot编写一个Controller,RestController等于@ResponseBody和@Controller的组合


@RestController  
public class HelloSpringBoot {  
    @RequestMapping("/hello")  
  
    public String helloSpringBoot() {  
        return "欢迎使用SpringBoot";  
    }  
  
    public HelloSpringBoot() {  
    }  
}

配置文件,可以修改各种配置,如端口号

Pasted image 20240903103123.png 打包

Pasted image 20240903104317.png 注意:在配置没有问题情况下,出现错误,可能是新版本idea项目,默认可能没有Artifacts,需要手动添加

Pasted image 20240903111236.png Pasted image 20240903111130.png Pasted image 20240903123746.png 还需要把pom.xml中的skip标签注释掉,或者改为false Pasted image 20240903131045.png 终端执行成功 Pasted image 20240903131127.png