SpringBoot3外部化配置與aop實(shí)現(xiàn)方案
POM文件中為何要以繼承的方式引入SpringBoot?
繼承父工程的優(yōu)勢(shì)
- 依賴管理:在父工程中定義依賴的版本,子模塊直接引用而不必指定版本號(hào)
- 插件管理:在父工程中配置插件,子模塊直接使用
- 屬性設(shè)置:在父工程中定義一些通用屬性,如項(xiàng)目編碼、java版本等
- 統(tǒng)一配置:可以統(tǒng)一多個(gè)子模塊的構(gòu)建配置,確保一致性。
繼承了父工程,那么引入依賴的時(shí)候不需要指定版本號(hào),因?yàn)樵诟腹こ讨?,各種依賴的版本號(hào)已經(jīng)預(yù)設(shè)好了。
SpringBoot核心注解
@SpringBootApplication
被此標(biāo)注表示該類是SpringBoot項(xiàng)目的入口類。
此注解被以下三個(gè)注解標(biāo)注,說(shuō)明@SpringBootApplication同時(shí)有以下三個(gè)注解的功能
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
@SpringBootConfiguration
@SpringBootConfiguration被@Configuration標(biāo)注說(shuō)明項(xiàng)目的主入口類同時(shí)是一個(gè)配置類,因此在主入口類中使用@Bean注解方法的話,該方法返回值對(duì)象會(huì)被納入Ioc容器管理。
@EnableAutoConfiguration
啟用自動(dòng)配置,SpringBoot默認(rèn)情況下啟用自動(dòng)配置。
自動(dòng)配置有什么用?
自動(dòng)配置只要啟動(dòng),SpringBoot就會(huì)去類路徑中查找Class。根據(jù)類路徑中有某些類來(lái)自動(dòng)管理Bean,不需要程序員手動(dòng)配置。
比如SpringBoot檢測(cè)到SqlSessionFactory,或者在application.properties中配置了數(shù)據(jù)源,SpringBoot會(huì)認(rèn)為項(xiàng)目中含有MyBatis框架,會(huì)將MyBatis相關(guān)的Bean初始化,然后放到Ioc容器中管理起來(lái)。
@ComponentScan
@ComponentScan負(fù)責(zé)組件掃描。會(huì)掃描此包及此包下所有子包或子包的子包等的路徑。
外部化配置
外部化配置是指將配置信息存儲(chǔ) 在應(yīng)用程序代碼之外的地方。這樣配置信息獨(dú)立于 代碼進(jìn)行管理。方便配置修改。修改后不需要重新編譯,也不需要重新部署。
springboot默認(rèn)先找外部化配置
Application.properites
- Application.properites配置文件是SpringBoot默認(rèn)的額配置文件
- Application.properites不是必須的,SpringBoot提供了默認(rèn)配置,如果需要修改默認(rèn)配置,就在Application.properites中進(jìn)行配置。
- Application.properites可以放在類路徑中,也可以放在項(xiàng)目之外,因此成為外部化配置
SpringBoot在啟動(dòng)時(shí)會(huì)從以下位置按順序加載Application.properites:
- file:./config/: 首先在SpringBoot當(dāng)前工作目錄下的config文件夾中查找(如果沒(méi)找到Application.properites,會(huì)繼續(xù)查找Application.yml,2個(gè)都沒(méi)找到,才會(huì)進(jìn)入下一個(gè)位置查找,以此類推)
- file:./: 這里找不到會(huì)繼續(xù)查找下一個(gè)位置
- classpath:/config/:
- classpath:/
如果在多個(gè)位置有相同屬性的定義,那么最先檢查的位置中的屬性值先使用。
如果要指定配置文件位置,可以通過(guò)--spring.config.location=進(jìn)行指定,比如:
java -jar xxxx.jar --spring.config.location=file:///E:\a\b\application.properties
注意:以上的--spring.config.location=file:///E:\a\b\application.properties屬于命令行參數(shù),會(huì)被傳遞到main方法的(String[] args)參數(shù)上。
讀取配置
// 讀取配置文件中myapp.path的值,
// 如果這個(gè)key不存在,并且沒(méi)有指定默認(rèn)值,那么會(huì)報(bào)錯(cuò)
// ${myapp.path:50}指定myapp.path的默認(rèn)值是50
@Value("${myapp.path:50}")
private String appPath;YAML語(yǔ)法規(guī)則
數(shù)據(jù)結(jié)構(gòu)
- 支持多種數(shù)據(jù)結(jié)構(gòu),包括:字符串、數(shù)字、布爾值、數(shù)組、List集合、Map鍵值對(duì)等
- yaml使用一個(gè)空格來(lái)分割屬性名和屬性值,比如:
name: jack
- yaml使用換行+空格表示層級(jí)關(guān)系,注意不能使用tab 必須是空格,空格數(shù)量無(wú)要求,建議2個(gè)或4個(gè),比如:
myapp: name: mall
- 同級(jí)元素左側(cè)對(duì)其
- 大小寫敏感
- 使用# 進(jìn)行注釋
- 在一個(gè)映射中,鍵必須唯一
- 普通文本可以使用單引號(hào),也可以使用雙引號(hào),也可以什么都不用(單引號(hào)中的\n表示普通文本,雙引號(hào)中的\n表示換行)
- 保留文本原格式使用 | 比如:
username: | aaaa bbb ccc
- 文檔切割: --- 這個(gè)符號(hào)下面的配置認(rèn)為是一個(gè)獨(dú)立的yaml文件,便于大文件的閱讀。
配置文件合并
#properties文件合并 # 對(duì)于數(shù)組來(lái)說(shuō),使用逗號(hào)進(jìn)行分隔開(kāi) spring.config.import=classpath:/application-mysql.properties,classpath:/application-redis.properties
yml文件合并的第一種寫法
spring:
config:
import: [classpath:/application-mysql.yml,classpath:/application-redis.yml]yml文件合并的第二種寫法
spring:
config:
import:
- classpath:/application-mysql.yml
- classpath:/application-redis.yml多環(huán)境切換
開(kāi)發(fā)環(huán)境配置文件:application-dev.properties
測(cè)試環(huán)境配置文件:application-test.properties
預(yù)生產(chǎn)環(huán)境配置文件:application-preprod.properties
生產(chǎn)環(huán)境配置文件:application-prod.properties
如果啟用生產(chǎn)環(huán)境配置,可以有以下兩種操作方式:
- 在application.properties添加配置:spring.profiles.active=prod
- 在命令行參數(shù)上添加: --spring.profiles.active=prod
將配置綁定到簡(jiǎn)單Bean
package com.ali.bindtobean.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
// 納入Ioc容器
@Component
// 將配置文件一次性綁定到Bean對(duì)象上
@ConfigurationProperties(prefix = "myapp")
public class AppConfig {
// 要實(shí)現(xiàn)一次性綁定,配置文件中的屬性名 必須和Bean對(duì)象的屬性名要一致
// 底層在給對(duì)象屬性賦值時(shí),調(diào)用了setter方法,因此每個(gè)屬性必須有setter方法
private String name;
private Integer age;
private String password;
private Boolean gender;
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;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Boolean getGender() {
return gender;
}
public void setGender(Boolean gender) {
this.gender = gender;
}
@Override
public String toString(){
return "AppConfig [name=" + name + ", age=" + age + ", gender=" + gender + "]";
}
}spring.application.name=bindtobean myapp.name=jack myapp.age=12 myapp.password=123 myapp.gender=true
綁定嵌套Bean
在一個(gè)Bean的屬性中,有一個(gè)其他Bean類型。這樣就是嵌套Bean。
package com.ali.bindtobean.bean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "app.xyz")
public class User {
private String name;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User [name=" + name + ", address=" + address.toString() + "]";
}
}package com.ali.bindtobean.bean;
public class Address {
private String city;
private String street;
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
@Override
public String toString() {
return "Address [city=" + city + ", street=" + street + "]";
}
}app.xyz.name=lucy app.xyz.address.city=xj app.xyz.address.street=dayang
其他方式綁定Bean
// 在主入口程序添加以下注解,啟用將配置信息綁定到User這個(gè)Bean
@EnableConfigurationProperties({User.class, Address.class})
另一種方式:
// 在主入口程序添加以下注解,掃面指定包。將配置信息綁定到這個(gè)包下的類 @ConfigurationPropertiesScan(basePackages = "com.ali.bindtobean.bean")
復(fù)雜的屬性結(jié)構(gòu)綁定Bean
綁定數(shù)組、集合、Map到Bean
app2.abc.names[0]=jack app2.abc.names[1]=lucy app2.abc.names[2]=tom app2.abc.addresses[0].city=bj app2.abc.addresses[0].street=chaoyang app2.abc.addresses[1].city=tj app2.abc.addresses[1].street=nankai app2.abc.addressList[0].city=bj_list app2.abc.addressList[0].street=chaoyang_list app2.abc.addressList[1].city=tj_list app2.abc.addressList[1].street=nankai_list # addr1 和addr2 都是key app2.abc.addressMap.addr1.city=bj_map app2.abc.addressMap.addr1.street=chaoyang_map app2.abc.addressMap.addr2.city=tj_map app2.abc.addressMap.addr2.street=nankai_map
yaml文件配置方式如下:
app2:
abc:
names:
- tom
- smith
addresses:
- city: beijing
street: chaoyang
- city: tianjin
street: nankai
# addressList 可以寫成 address-list
addressList:
- city: beijing
street: chaoyang
- city: tianjin
street: nankai
addressMap:
addr1:
city: beijing
street: chaoyang
addr2:
city: tianjin
street: nankaipackage com.ali.bindtobean.bean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Map;
@ConfigurationProperties(prefix = "app2.abc")
public class AppBean {
// 數(shù)組中元素是簡(jiǎn)單類型
private String[] names;
// 數(shù)組中元素是Bean
private Address[] addresses;
//List集合。List中元素是Bean
private List<Address> addressList;
//Map集合: String,Bean
private Map<String,Address> addressMap;
public void setNames(String[] names) {
this.names = names;
}
public void setAddresses(Address[] addresses) {
this.addresses = addresses;
}
public void setAddressList(List<Address> addressList) {
this.addressList = addressList;
}
public void setAddressMap(Map<String, Address> addressMap) {
this.addressMap = addressMap;
}
@Override
public String toString() {
return "";
}
}將配置綁定到第三方對(duì)象
other:
abc:
city: beijing
street: daxingpackage com.ali.bindtobean.config;
import com.ali.bindtobean.bean.Address;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig2 {
// address 是第三方類,使用以下方式完成配置到屬性的綁定
@Bean
@ConfigurationProperties(prefix = "other.abc")
public Address address() {
return new Address();
}
}指定配置數(shù)據(jù)來(lái)源
@Component
@ConfigurationProperties(prefix = "app2.abc")
// 指定配置數(shù)據(jù)來(lái)自/a/b/group-info.properties路徑的配置文件
@PropertySource("classpath:/a/b/group-info.properties")
public class AppBean {
...
}
@ImportResource注解
當(dāng)SpringBoot項(xiàng)目中出現(xiàn)ApplicationContext.xml文件。并且文件中配置了Bean。要把這個(gè)Bean注入到容器中。
package com.ali.bindtobean.bean;
public class Person {
private String name;
private int 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;
}
@Override
public String toString() {
return super.toString();
}
}配置文件如下:
<?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="person" class="com.ali.bindtobean.bean.Person">
<property name="name" value="jack"/>
<property name="age" value="20"/>
</bean>
</beans>// 在主入口程序添加以下注解讓applocationContext.xml文件生效
@ImportResource("classpath:/applocationContext.xml")
Environment
spring提供的一個(gè)接口。SpringBoot啟動(dòng)的時(shí)候會(huì)把環(huán)境、系統(tǒng)信息封裝到Environment對(duì)象中,需要獲取這些信息,可使用Environment接口的方法。
Environment對(duì)象主要包括
- 當(dāng)前激活的配置文件 active-profiles
- 系統(tǒng)屬性,如系統(tǒng)名字 、java版本
- 環(huán)境變量
- 應(yīng)用程序啟動(dòng)時(shí)傳給主方法的命令行參數(shù)
@Autowired
private Environment environment;
public void doSomething() {
// 獲取當(dāng)前激活的配置文件
String[] activeProfiles = environment.getActiveProfiles();
for (String activeProfile : activeProfiles) {
System.out.println(activeProfile);
}
// 獲取配置信息
String property = environment.getProperty("app.xyz.address.city");
System.out.println(property);
}SpringBoot aop實(shí)現(xiàn)
添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>3.3.5</version>
</dependency>編寫切面類
package com.ali.springaop.component;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.stereotype.Component;
import java.util.Arrays;
// 指定切面類
@Aspect
@Component
public class LoggingAspect {
private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);
// 定義切入點(diǎn),匹配所有以“service”結(jié)尾的包下的所有方法
@Pointcut("execution(* com.ali.springaop.service..*(..))")
public void ServiceMethods(){
}
// 前置通知,切入點(diǎn)的方法執(zhí)行前執(zhí)行此代碼
@Before("ServiceMethods()")
public void before(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
logger.info("Method [{}] with parameters [{}] is called", methodName, Arrays.toString(args));
}
}到此這篇關(guān)于SpringBoot3外部化配置與aop實(shí)現(xiàn)方案的文章就介紹到這了,更多相關(guān)SpringBoot外部化配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot外部化配置的最佳實(shí)踐指南
- SpringBoot外部化配置示例解析
- SpringBoot擴(kuò)展外部化配置的原理解析
- 詳解關(guān)于SpringBoot的外部化配置使用記錄
- SpringBoot外部化配置使用Plus版的方法示例
- SpringBoot中四種AOP實(shí)戰(zhàn)應(yīng)用場(chǎng)景及代碼實(shí)現(xiàn)
- Springboot+aop實(shí)現(xiàn)配置多數(shù)據(jù)源的示例代碼
- SpringBoot中基于AOP和Semaphore實(shí)現(xiàn)API限流
- SpringBoot實(shí)現(xiàn)AOP切面的三種方式
相關(guān)文章
Tomcat 實(shí)現(xiàn)WebSocket詳細(xì)介紹
這篇文章主要介紹了Tomcat 如何實(shí)現(xiàn)WebSocket的相關(guān)資料,對(duì)WebSocket協(xié)議通信的過(guò)程進(jìn)行了詳細(xì)介紹,需要的朋友可以參考下2016-12-12
Java線程池內(nèi)部任務(wù)出異常后發(fā)現(xiàn)異常的3種方法
Java線程池是一種并發(fā)編程工具,它允許開(kāi)發(fā)者以線程池的形式重用線程,從而避免頻繁創(chuàng)建和銷毀線程所帶來(lái)的開(kāi)銷,這篇文章主要給大家介紹了關(guān)于Java線程池內(nèi)部任務(wù)出異常后發(fā)現(xiàn)異常的3種方法,需要的朋友可以參考下2025-07-07
使用nacos實(shí)現(xiàn)自定義文本配置的實(shí)時(shí)刷新
我們都知道,使用Nacos時(shí),如果將Bean使用@RefreshScope標(biāo)注之后,這個(gè)Bean中的配置就會(huì)做到實(shí)時(shí)刷新,本文給大家介紹了如何使用nacos實(shí)現(xiàn)自定義文本配置的實(shí)時(shí)刷新,需要的朋友可以參考下2024-05-05

