参考:https://www.yuque.com/leifengyang/springboot2
参考:https://www.bilibili.com/video/BV19K4y1L7MT?p=1&vd_source=0c3c1f43c75954a15fba4e42c1d7883e
(资料图片)
项目结构
1. pom.xml
4.0.0 com.example springboot-test 1.0-SNAPSHOT pom springboot-01-hello org.springframework.boot spring-boot-starter-parent 2.3.4.RELEASE org.springframework.boot spring-boot-starter-web 8 8 UTF-8 org.springframework.boot spring-boot-maven-plugin
2. MainApplication
package com.example;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * 主程序类 * @SpringBootApplication:这是一个springboot应用 */@SpringBootApplicationpublic class MainApplication { public static void main(String[] args) { SpringApplication.run(MainApplication.class, args); }}
3. HelloController
package com.example.controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class HelloController { @RequestMapping("/hello") public String home() { return "Hello world"; }}
4. 启动服务,浏览器访问
org.springframework.boot spring-boot-starter-parent 2.3.4.RELEASE 点进spring-boot-starter-parent看到: org.springframework.boot spring-boot-dependencies 2.3.4.RELEASE 点进spring-boot-dependencies看到: 几乎声明了所有开发中常用的依赖的版本号
org.springframework.boot spring-boot-starter 2.3.4.RELEASE compile
5.1.43
org.springframework.boot spring-boot-starter-tomcat 2.3.4.RELEASE compile
配置Tomcat ???SpringBoot帮我们配置好了所有web开发的常见场景
dispatcherServlet字符编码:characterEncodingFilter文件上传:multipartResolver@SpringBootApplication等同于@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan("com.example")
package com.example;import org.springframework.boot.SpringApplication;import org.springframework.boot.SpringBootConfiguration;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.ComponentScan;/**@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan("com.example")等价于@SpringBootApplication(scanBasePackages="com.example") 默认扫描主程序所在的包*/@SpringBootApplicationpublic 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); } }}
package com.example.bean;public class User { private String name; private int age; private Pet pet; public User() { } public User(String name, int age) { this.name = name; this.age = age; } 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; } public Pet getPet() { return pet; } public void setPet(Pet pet) { this.pet = pet; } @Override public String toString() { return "User{" + "name="" + name + "\"" + ", age=" + age + ", pet=" + pet + "}"; }}
Petpackage com.example.bean;public class Pet { private String name; public Pet() { } public Pet(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Pet{" + "name="" + name + "\"" + "}"; }}
MainConfigpackage com.example.config;import com.example.bean.Pet;import com.example.bean.User;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuration(proxyBeanMethods=true) // 告诉springboot这是一个配置类public class MainConfig { @Bean public User userBean(){ User u = new User("zhangsan", 18); u.setPet(petBean()); return u; } @Bean public Pet petBean(){ Pet p = new Pet("cat"); return p; }}
MainApplicationpackage com.example;import com.example.bean.Pet;import com.example.bean.User;import com.example.config.MainConfig;import org.springframework.boot.SpringApplication;import org.springframework.boot.SpringBootConfiguration;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.ComponentScan;/**@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan("com.example")等价于@SpringBootApplication(scanBasePackages="com.example") 默认扫描主程序所在的包*/@SpringBootApplicationpublic 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. 从容器中获取组件 User user = (User) run.getBean("userBean"); User user2 = (User) run.getBean("userBean"); System.out.println("组件默认是单例的:" + (user==user2)); // 4. 配置类也是组件 MainConfig bean = run.getBean(MainConfig.class); System.out.println("配置类本身也是组件:" + bean); // 5. proxyBeanMethods = true, mainConfig就是被增强的代理对象 // springboot总会检查组件是否在容器中存在 // 保持组件单实例 // 外部无论对配置类中的这个组件注册方法调用多少次,获取的都是之前注册容器中的单实例对象 User user3 = bean.userBean(); User user4 = bean.userBean(); System.out.println("主配置是否为代理对象: "+(user3==user4)); // full: proxyBeanMethods=true => 应用场景: 解决组件依赖 // lite: proxyBeanMethods=false => 配置类在容器中不会保存代理对象,在外边调用方法,每次都会产生一个新对象 // Full: 保证每个@Bean方法被调用多少次返回的组件都是单实例的。类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式 // Lite: 每个@Bean方法被调用多少次返回的组件都是新创建的。类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断 // 组件依赖必须使用Full模式默认。其他默认是否Lite模式 Pet pet = (Pet) run.getBean("petBean"); System.out.println("proxyBeanMethods组件依赖" + (user.getPet()==pet)); }}
package com.example.config;import com.example.bean.Pet;import com.example.bean.User;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class MainConfig {}
Userpackage com.example.bean;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Component;import javax.annotation.Resource;@Component("userBean")public class User { private String name; private int age; @Autowired private Pet pet; public User() { } public User(String name, int age) { this.name = name; this.age = age; } 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; } public Pet getPet() { return pet; } public void setPet(Pet pet) { this.pet = pet; } @Override public String toString() { return "User{" + "name="" + name + "\"" + ", age=" + age + ", pet=" + pet + "}"; }}
Petpackage com.example.bean;import org.springframework.stereotype.Component;@Component("petBean")public class Pet { private String name; public Pet() { } public Pet(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Pet{" + "name="" + name + "\"" + "}"; }}
MainApplicationpackage com.example;import com.example.bean.Pet;import com.example.bean.User;import com.example.config.MainConfig;import org.springframework.boot.SpringApplication;import org.springframework.boot.SpringBootConfiguration;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.ComponentScan;/** * @SpringBootConfiguration * @EnableAutoConfiguration * @ComponentScan("com.example") 等价于@SpringBootApplication(scanBasePackages="com.example") * 默认扫描主程序所在的包 */@SpringBootApplicationpublic 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. 从容器中获取组件 User user = (User) run.getBean("userBean"); User user2 = (User) run.getBean("userBean"); System.out.println("组件默认是单例的:" + (user == user2)); // 4. 配置类也是组件 MainConfig bean = run.getBean(MainConfig.class); System.out.println("配置类本身也是组件:" + bean); // 5. 组件依赖 Pet pet = (Pet) run.getBean("petBean"); System.out.println("组件依赖" + (user.getPet() == pet)); }}
@Import:给容器中自动创建出指定类型的组件、默认组件的名字就是全类名
@Conditional:条件装配,满足Conditional指定的条件,则进行组件注入
@ImportResource:原生配置文件引入
@ConfigurationProperties:配置文件中的配置项绑定给组件的属性
项目结构MainApplicationpackage com.example;import ch.qos.logback.core.db.DBHelper;import com.example.bean.Pet;import com.example.bean.User;import com.example.config.MainConfig;import org.springframework.boot.SpringApplication;import org.springframework.boot.SpringBootConfiguration;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.ComponentScan;import java.util.Arrays;/** @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan("com.example") 等价于@SpringBootApplication(scanBasePackages="com.example") 默认扫描主程序所在的包 *//** * @Import:给容器中自动创建出指定类型的组件、默认组件的名字就是全类名 * @Conditional:条件装配,满足Conditional指定的条件,则进行组件注入 * @ImportResource:原生配置文件引入 * @ConfigurationProperties:配置文件中的配置项绑定给组件的属性 */@SpringBootApplicationpublic 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. 获取组件 Boolean flag = run.containsBean("petBean"); System.out.println("容器中是否存在petBean组件:" + flag); Boolean flag2 = run.containsBean("userBean"); System.out.println("容器中是否存在userBean组件:" + flag2); // 4. 容器中组件数量 System.out.println("组件数量:" + run.getBeanDefinitionCount()); // 167 }}
mainApplication.xml
Userpackage com.example.bean;public class User { private String name; private int age; private Pet pet; public User() { } public User(String name, int age) { this.name = name; this.age = age; } 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; } public Pet getPet() { return pet; } public void setPet(Pet pet) { this.pet = pet; } @Override public String toString() { return "User{" + "name="" + name + "\"" + ", age=" + age + ", pet=" + pet + "}"; }}
Petpackage com.example.bean;public class Pet { private String name; public Pet() { } public Pet(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Pet{" + "name="" + name + "\"" + "}"; }}
Carpackage com.example.bean;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;// @Component // MainConfig中使用了@EnableConfigurationProperties(Car.class),则不用@Component@ConfigurationProperties(prefix = "car")public class Car { private String brand; private double price; public Car() { } public Car(String brand, double price) { this.brand = brand; this.price = price; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "Car{" + "brand="" + brand + "\"" + ", price=" + price + "}"; }}
MainConfigpackage com.example.config;import ch.qos.logback.core.db.DBHelper;import com.example.bean.Car;import com.example.bean.Pet;import com.example.bean.User;import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.context.annotation.*;// @ConditionalOnBean(name="petBean") // 有petBean类里的组件注册才生效,否则都不生效@EnableConfigurationProperties(Car.class)// @EnableConfigurationProperties(Car.class)的作用:// 1. 开启Car配置绑定功能// 2. 把这个Car这个组件自动注册到容器中@ImportResource("classpath:mainApplication.xml")@Import({User.class, DBHelper.class})@Configuration(proxyBeanMethods=true) // 告诉springboot这是一个配置类public class MainConfig { @ConditionalOnBean(name="petBean") // 容器中存在petBean才执行userBean的组件注册 @Bean public User userBean(){ User u = new User("zhangsan", 18); u.setPet(petBean()); return u; } // @Bean public Pet petBean(){ Pet p = new Pet("cat"); return p; }}
@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class}), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class})})public @interface SpringBootApplication {}
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Configuration // SpringBootConfiguration用来注解 配置类 => MainApplication是一个配置类(核心配置类)public @interface SpringBootConfiguration { @AliasFor( annotation = Configuration.class ) boolean proxyBeanMethods() default true;}
@AutoConfigurationPackage@Import({AutoConfigurationImportSelector.class})public @interface EnableAutoConfiguration {}
@AutoConfigurationPackage@Import({AutoConfigurationPackages.Registrar.class}) // 给容器中导入一个组件// 指定了默认的包规则public @interface AutoConfigurationPackage {}// 利用Registrar给容器中导入一系列组件// 将指定的MainApplication所在包下的所有组件导入进来
@Import({AutoConfigurationImportSelector.class})1. 利用getAutoConfigurationEntry(annotationMetadata)给容器中批量导入一些组件2. 调用List configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类3. 利用工厂加载 Map> loadSpringFactories(@Nullable ClassLoader classLoader)得到所有的组件4. 从META-INF/spring.factories位置来加载一个文件。 默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件 spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories 文件里面写死了spring-boot一启动就要给容器中加载的所有配置类
1. 虽然我们127个场景的所有自动配置启动的时候默认全部加载。 META-INF/spring.factories文件中:xxxxAutoConfiguration2. 按照条件装配规则(@Conditional),最终会按需配置。 eg. @ConditionalOnClass({Gson.class})
@Bean@ConditionalOnBean(MultipartResolver.class) //容器中有这个类型组件@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件public MultipartResolver multipartResolver(MultipartResolver resolver) { //给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。 //SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范// Detect if the user has created a MultipartResolver but named it incorrectlyreturn resolver;}
SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先
@Bean@ConditionalOnMissingBeanpublic CharacterEncodingFilter characterEncodingFilter() {}
总结:
SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定生效的配置类就会给容器中装配很多组件(pom.xml配置了)只要容器中有这些组件,相当于这些功能就有了定制化配置用户直接自己@Bean替换底层的组件用户去看这个组件是获取的配置文件什么值就去修改。xxxxxAutoConfiguration ---> 组件 ---> xxxxProperties里面拿值 ----> application.properties
spring.banner.image.location=classpath:timg.jpg
org.projectlombok lombok
idea安装插件使用@ToString // toString@Data // getter、setter@AllArgsConstructor // 全参构造器@NoArgsConstructor // 无参构造器@Slf4j // 日志
例子package com.example.bean;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.ToString;@ToString // toString@Data // getter、setter@AllArgsConstructor // 全参构造器@NoArgsConstructor // 无参构造器public class LombokBean { private String str; private int i;}
import com.example.bean.LombokBean;import lombok.extern.slf4j.Slf4j;import org.junit.Test;@Slf4jpublic class LombokBeanTest { @Test public void testLombokBean(){ LombokBean o = new LombokBean(); o.setStr("abc"); o.setI(10); System.out.println(o); log.info(o.toString()); }}
参考:https: www yuque com leifengyang springboot2
我们每天都吃五六颗红枣红枣是补血的每天都可以当零食吃蒸熟了也可以吃最好的方法是把红枣洗干净,蒸熟了放在冰箱里面但是时间只能三天以内就
甘肃省举办职业技能等级认定考评员培训
我原来想三台车都上马力机,是不是很大胆?一挡混动、两挡混动、三挡混动,都拉马力。就那一个坐标系,就完全是那个坐标系,放三条曲线,一目
一季度我国人民币贷款增加10 6万亿元,对实体经济发放的人民币贷款占同期社会融资规模的73 6%……最新出炉的首季金融统计数据亮点不少,呈现信
全国最大禽蛋交易市场将在馆陶迁址重建总投资18亿元,建成运营后,预计年交易额超200亿元纵览客户端讯(河北日报记者刘剑英
华尔街谈AI炒股:股市本质上就不是AI能赢的领域,股市,华尔街,炒股,股票,ai,基金
新华社北京4月12日电外交部发言人汪文斌12日宣布:应国务委员兼外交部长秦刚邀请,德国外长贝尔伯克将于4月13日至15日对中国进行正式访问。其
有关系特别好的女性朋友,可以送一些比较有创意的礼物,像是定制的抱枕、抱枕、抱枕、抱枕、抱枕等等,这些礼物都是很适合送女性
1、刑法修正案一共有十个,刑法修正案(十一)草案已经提出。2、1999年的刑法修正案(一),2001年的刑法修正案(二)
今天来聊聊关于稳心颗粒可以长期吃有副作用吗,稳心颗粒可以长期吃的文章,现在就为大家来简单介绍下稳心颗粒可以长期吃有副作用
科陆电子(002121)4月12日在互动平台回答投资者提问时表示,目前公司储能产品采用磷酸铁锂电池。本文到此结束,希望对
电池级碳酸锂价格跌破20万元 吨大关。
川观新闻记者史晓露4月12日,国家统计局四川调查总队发布的数据显示,2023年3月,四川工业生产者出厂价格指数(简称:PPI)同比下降1 6%,环比
这是两部在网络上很难找到剧透的戏剧。观众能看到的,是它们在豆瓣上8 6的高分,和越来越多人在社交平台的“自来水”留言。它们便是正在上海文
安徽安庆市正式成立“老年助餐慈善基
记者日前从安庆市民政局获悉,该市慈善会近日设立老年助餐慈善基金,共同守护老年人舌尖上的幸福。该基金专项用于资助城乡社区老年食堂、社
安徽淮北积极落实2022年电网防汛度汛
近日,国网淮北供电公司工作人员来到110千伏中泰变电站开展防汛隐患排查。该公司积极落实2022年防汛度汛措施,提前细化应急预案,推进极端
安徽全椒县完善拓展人力信息资源助企
今年以来,全椒县不断完善拓展人力资源信息库、劳务对接信息库、企业用工需求信息库三库信息资源,已摸排400多家次企业缺工岗位信息1 2万个
宿州市埇桥区柔性引进博士推进乡村振
宿州市埇桥区实施博士汇工程,柔性引进29名博士担任副乡镇长或园区副主任,他们将为加快产业发展、推进乡村振兴强化智力支持。目前,博士专
安徽印发出台全面实施零基预算改革方
为进一步提高财政资源配置效率和资金使用效益,省政府印发《安徽省全面实施零基预算改革方案》,明确从编制2023年预算起,在全省范围内全面
5月份安徽居民消费价格同比上涨2.3%
近日,国家统计局安徽调查总队发布了我省5月份居民消费价格统计数据。统计显示,我省居民消费价格同比上涨2 3%,同比涨幅比上月回落0 4个百分
安徽多种方式引导群众防范非法集资风
合肥地铁1号线、3号线上滚动播放防范非法集资宣传视频,淮南市发布《致老年群众的一封信》……6月份是一年一度防范和处置非法集资宣传月,今
铁路部门持续加大长三角地区运力投放
记者从中国铁路上海局集团有限公司获悉,随着上海疫情防控形势持续向好,为进一步适应旅客出行需要,助力复工复产,铁路部门自6月10日起持续加
安徽六安持续精准施策全力促进工业发
六安市与蔚来汽车签署合作协议,共建智能电动汽车零部件配套产业园区。该园区一期计划2023年上半年投产,建成后将具备年产30万吨铝压铸产能,
安徽淮北全力维护外卖送餐员合法权益
为切实防范化解新业态领域重大风险隐患,强化外卖送餐员权益保障工作,淮北市市场监管局充分发挥职能作用,全力维护外卖送餐员合法权益。淮北
湖南涟源开展专项行动一对一为企业纾
位于涟源市的湖南三合美新材料科技有限公司,两条生产线满负荷运行,生产聚氨酯和岩棉复合板。因产品升级与产能扩充,急需新增两条生产线,
湖南蓝山县进村入户排查整治自建房安
老叔,这栋房屋墙体有开裂痕迹,要维修加固,安全重要!5月20日,蓝山县塔峰镇果木村,党员干部上门开展农村自建房安全隐患排查整治。连日来
一季度湖南万元产值综合能耗同比下降
近日,湖南省工业通信业节能监察中心发布一季度全省六大高耗能行业能源消耗统计监测报告。据该报告,一季度全省146家主要高耗能企业的万元
济南起步区一年来累计签约优质项目11
万里黄河第一隧济南黄河济泺路隧道建成通车,占地4000余亩的新能源乘用车零部件产业园加快施工……记者21日采访获悉,建设实施方案获批复一
山东发布通知启动传统民居保护利用试
省住房城乡建设厅、省财政厅近日联合印发《关于做好传统民居保护利用试点工作的通知》,在全省部署开展传统民居保护利用试点工作。此次试点