參考: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日采訪獲悉,建設實施方案獲批復一
山東發布通知啟動傳統民居保護利用試
省住房城鄉建設廳、省財政廳近日聯合印發《關于做好傳統民居保護利用試點工作的通知》,在全省部署開展傳統民居保護利用試點工作。此次試點