前言:之前和一些视频学习 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);
}
}
打印结果
通过扫描装配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 {
}
打印结果
@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("这是猫");
}
}
打印结果
如果再增加狗类
则会出现找到两个Bean的问题
@Autowired提供了这样的规则:首先根据类型类型找对应的Bean
此时修改@Autowired修饰的属性修改为狗即可
消除歧义性 @ Primary 和 @ Quelifier
@ Primary:它是一个修改优先权的注解,在cat标注后如果同时有多个Bean,使用@Primary 修饰的
@Primary
public class Cat implements Animal {
@Override
public void use() {
System.out.println("这是猫");
}
}
打印结果
@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
打印结果
以下是和视频学遇到的坑,希望能帮大家规避
# 服务端口
server.port=8080
# Springlogo图
spring.main.banner-mode=off
配置文件优先级 properties > yml > yaml
上手
@SpringBootApplication
表示这是一个Spring Boot应用程序
是主程序类,入口
编写一个Controller
@Controller
public class HelloSpringBoot {
@RequestMapping("/hello")
@ResponseBody
public String helloSpringBoot() {
return "欢迎使用SpringBoot";
}
public HelloSpringBoot() {
}
}
Spring Boot编写一个Controller,RestController等于@ResponseBody和@Controller的组合
@RestController
public class HelloSpringBoot {
@RequestMapping("/hello")
public String helloSpringBoot() {
return "欢迎使用SpringBoot";
}
public HelloSpringBoot() {
}
}
配置文件,可以修改各种配置,如端口号
打包
注意:在配置没有问题情况下,出现错误,可能是新版本idea项目,默认可能没有Artifacts,需要手动添加
还需要把pom.xml中的skip标签注释掉,或者改为false
终端执行成功