找回密码
 立即注册
首页 业界区 业界 SpringBoot3-外部化配置与aop实现

SpringBoot3-外部化配置与aop实现

季卓然 2026-1-20 13:00:05
POM文件中为何要以继承的方式引入SpringBoot?

继承父工程的优势


  • 依赖管理:在父工程中定义依赖的版本,子模块直接引用而不必指定版本号
  • 插件管理:在父工程中配置插件,子模块直接使用
  • 属性设置:在父工程中定义一些通用属性,如项目编码、java版本等
  • 统一配置:可以统一多个子模块的构建配置,确保一致性。
继承了父工程,那么引入依赖的时候不需要指定版本号,因为在父工程中,各种依赖的版本号已经预设好了。
SpringBoot核心注解

@SpringBootApplication

被此标注表示该类是SpringBoot项目的入口类。
此注解被以下三个注解标注,说明@SpringBootApplication同时有以下三个注解的功能
  1. @SpringBootConfiguration
  2. @EnableAutoConfiguration
  3. @ComponentScan
复制代码
@SpringBootConfiguration

@SpringBootConfiguration被@Configuration标注说明项目的主入口类同时是一个配置类,因此在主入口类中使用@Bean注解方法的话,该方法返回值对象会被纳入Ioc容器管理。
@EnableAutoConfiguration

启用自动配置,SpringBoot默认情况下启用自动配置。
自动配置有什么用?
自动配置只要启动,SpringBoot就会去类路径中查找Class。根据类路径中有某些类来自动管理Bean,不需要程序员手动配置。
比如SpringBoot检测到SqlSessionFactory,或者在application.properties中配置了数据源,SpringBoot会认为项目中含有MyBatis框架,会将MyBatis相关的Bean初始化,然后放到Ioc容器中管理起来。
@ComponentScan

@ComponentScan负责组件扫描。会扫描此包及此包下所有子包或子包的子包等的路径。
外部化配置

外部化配置是指将配置信息存储 在应用程序代码之外的地方。这样配置信息独立于 代码进行管理。方便配置修改。修改后不需要重新编译,也不需要重新部署。
springboot默认先找外部化配置
Application.properites


  • Application.properites配置文件是SpringBoot默认的额配置文件
  • Application.properites不是必须的,SpringBoot提供了默认配置,如果需要修改默认配置,就在Application.properites中进行配置。
  • Application.properites可以放在类路径中,也可以放在项目之外,因此成为外部化配置
SpringBoot在启动时会从以下位置按顺序加载Application.properites:

  • file:./config/:  首先在SpringBoot当前工作目录下的config文件夹中查找(如果没找到Application.properites,会继续查找Application.yml,2个都没找到,才会进入下一个位置查找,以此类推)
  • file:./: 这里找不到会继续查找下一个位置
  • classpath:/config/:
  • classpath:/
如果在多个位置有相同属性的定义,那么最先检查的位置中的属性值先使用。
如果要指定配置文件位置,可以通过--spring.config.location=进行指定,比如:
  1. java -jar xxxx.jar --spring.config.location=file:///E:\a\b\application.properties
复制代码
注意:以上的--spring.config.location=file:///E:\a\b\application.properties属于命令行参数,会被传递到main方法的(String[] args)参数上。
读取配置
  1. // 读取配置文件中myapp.path的值,
  2. // 如果这个key不存在,并且没有指定默认值,那么会报错
  3.     // ${myapp.path:50}指定myapp.path的默认值是50
  4.     @Value("${myapp.path:50}")
  5.     private String appPath;
复制代码
YAML语法规则

数据结构


  • 支持多种数据结构,包括:字符串、数字、布尔值、数组、List集合、Map键值对等
  • yaml使用一个空格来分割属性名和属性值,比如:
  1. name: jack
复制代码

  • yaml使用换行+空格表示层级关系,注意不能使用tab 必须是空格,空格数量无要求,建议2个或4个,比如:
  1. myapp:
  2.   name: mall
复制代码

  • 同级元素左侧对其
  • 大小写敏感
  • 使用# 进行注释
  • 在一个映射中,键必须唯一
  • 普通文本可以使用单引号,也可以使用双引号,也可以什么都不用(单引号中的\n表示普通文本,双引号中的\n表示换行)
  • 保留文本原格式使用 |  比如:
  1. username: |
  2.   aaaa
  3.   bbb
  4.   ccc
复制代码

  • 文档切割: --- 这个符号下面的配置认为是一个独立的yaml文件,便于大文件的阅读。
配置文件合并
  1. #properties文件合并
  2. # 对于数组来说,使用逗号进行分隔开
  3. spring.config.import=classpath:/application-mysql.properties,classpath:/application-redis.properties
复制代码
yml文件合并的第一种写法
  1. spring:
  2.   config:
  3.     import: [classpath:/application-mysql.yml,classpath:/application-redis.yml]
复制代码
yml文件合并的第二种写法
  1. spring:
  2.   config:
  3.     import:
  4.       - classpath:/application-mysql.yml
  5.       - classpath:/application-redis.yml
复制代码
多环境切换

开发环境配置文件:application-dev.properties
测试环境配置文件:application-test.properties
预生产环境配置文件:application-preprod.properties
生产环境配置文件:application-prod.properties
如果启用生产环境配置,可以有以下两种操作方式:

  • 在application.properties添加配置:spring.profiles.active=prod
  • 在命令行参数上添加: --spring.profiles.active=prod
将配置绑定到简单Bean
  1. package com.ali.bindtobean.config;
  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. import org.springframework.context.annotation.Configuration;
  4. // 纳入Ioc容器
  5. @Component
  6. // 将配置文件一次性绑定到Bean对象上
  7. @ConfigurationProperties(prefix = "myapp")
  8. public class AppConfig {
  9.     // 要实现一次性绑定,配置文件中的属性名 必须和Bean对象的属性名要一致
  10.     // 底层在给对象属性赋值时,调用了setter方法,因此每个属性必须有setter方法
  11.   private String name;
  12.   private Integer age;
  13.   private String password;
  14.   private Boolean gender;
  15.     public String getName() {
  16.         return name;
  17.     }
  18.     public void setName(String name) {
  19.         this.name = name;
  20.     }
  21.     public Integer getAge() {
  22.         return age;
  23.     }
  24.     public void setAge(Integer age) {
  25.         this.age = age;
  26.     }
  27.     public String getPassword() {
  28.         return password;
  29.     }
  30.     public void setPassword(String password) {
  31.         this.password = password;
  32.     }
  33.     public Boolean getGender() {
  34.         return gender;
  35.     }
  36.     public void setGender(Boolean gender) {
  37.         this.gender = gender;
  38.     }
  39.     @Override
  40.     public String toString(){
  41.         return "AppConfig [name=" + name + ", age=" + age + ", gender=" + gender + "]";
  42.     }
  43. }
复制代码
  1. spring.application.name=bindtobean
  2. myapp.name=jack
  3. myapp.age=12
  4. myapp.password=123
  5. myapp.gender=true
复制代码
绑定嵌套Bean

在一个Bean的属性中,有一个其他Bean类型。这样就是嵌套Bean。
  1. package com.ali.bindtobean.bean;
  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. import org.springframework.stereotype.Component;
  4. @Component
  5. @ConfigurationProperties(prefix = "app.xyz")
  6. public class User {
  7.     private String name;
  8.     private Address address;
  9.     public Address getAddress() {
  10.         return address;
  11.     }
  12.     public void setAddress(Address address) {
  13.         this.address = address;
  14.     }
  15.     public String getName() {
  16.         return name;
  17.     }
  18.     public void setName(String name) {
  19.         this.name = name;
  20.     }
  21.     @Override
  22.     public String toString() {
  23.         return "User [name=" + name + ", address=" + address.toString() + "]";
  24.     }
  25. }
复制代码
  1. package com.ali.bindtobean.bean;
  2. public class Address {
  3.     private String city;
  4.     private String street;
  5.     public String getCity() {
  6.         return city;
  7.     }
  8.     public void setCity(String city) {
  9.         this.city = city;
  10.     }
  11.     public String getStreet() {
  12.         return street;
  13.     }
  14.     public void setStreet(String street) {
  15.         this.street = street;
  16.     }
  17.     @Override
  18.     public String toString() {
  19.         return "Address [city=" + city + ", street=" + street + "]";
  20.     }
  21. }
复制代码
  1. app.xyz.name=lucy
  2. app.xyz.address.city=xj
  3. app.xyz.address.street=dayang
复制代码
其他方式绑定Bean
  1. // 在主入口程序添加以下注解,启用将配置信息绑定到User这个Bean
  2. @EnableConfigurationProperties({User.class, Address.class})
复制代码
另一种方式:
  1. // 在主入口程序添加以下注解,扫面指定包。将配置信息绑定到这个包下的类
  2. @ConfigurationPropertiesScan(basePackages = "com.ali.bindtobean.bean")
复制代码
复杂的属性结构绑定Bean

绑定数组、集合、Map到Bean
  1. app2.abc.names[0]=jack
  2. app2.abc.names[1]=lucy
  3. app2.abc.names[2]=tom
  4. app2.abc.addresses[0].city=bj
  5. app2.abc.addresses[0].street=chaoyang
  6. app2.abc.addresses[1].city=tj
  7. app2.abc.addresses[1].street=nankai
  8. app2.abc.addressList[0].city=bj_list
  9. app2.abc.addressList[0].street=chaoyang_list
  10. app2.abc.addressList[1].city=tj_list
  11. app2.abc.addressList[1].street=nankai_list
  12. # addr1 和addr2 都是key
  13. app2.abc.addressMap.addr1.city=bj_map
  14. app2.abc.addressMap.addr1.street=chaoyang_map
  15. app2.abc.addressMap.addr2.city=tj_map
  16. app2.abc.addressMap.addr2.street=nankai_map
复制代码
yaml文件配置方式如下:
  1. app2:
  2.     abc:
  3.         names:
  4.           - tom
  5.           - smith
  6.         addresses:
  7.             - city: beijing
  8.               street: chaoyang
  9.             - city: tianjin
  10.               street: nankai
  11.        # addressList 可以写成 address-list
  12.         addressList:
  13.             - city: beijing
  14.               street: chaoyang
  15.             - city: tianjin
  16.               street: nankai
  17.         addressMap:
  18.             addr1:
  19.                 city: beijing
  20.                 street: chaoyang
  21.             addr2:
  22.                 city: tianjin
  23.                 street: nankai
复制代码
  1. package com.ali.bindtobean.bean;
  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. import java.util.Map;
  4. @ConfigurationProperties(prefix = "app2.abc")
  5. public class AppBean {
  6.     // 数组中元素是简单类型
  7.     private String[] names;
  8.     // 数组中元素是Bean
  9.     private Address[] addresses;
  10.     //List集合。List中元素是Bean
  11.     private  List addressList;
  12.     //Map集合: String,Bean
  13.     private Map<String,Address> addressMap;
  14.     public void setNames(String[] names) {
  15.         this.names = names;
  16.     }
  17.     public void setAddresses(Address[] addresses) {
  18.         this.addresses = addresses;
  19.     }
  20.     public void setAddressList(List addressList) {
  21.         this.addressList = addressList;
  22.     }
  23.     public void setAddressMap(Map<String, Address> addressMap) {
  24.         this.addressMap = addressMap;
  25.     }
  26.     @Override
  27.     public String toString() {
  28.         return "";
  29.     }
  30. }
复制代码
将配置绑定到第三方对象
  1. other:
  2.   abc:
  3.     city: beijing
  4.     street: daxing
复制代码
  1. package com.ali.bindtobean.config;
  2. import com.ali.bindtobean.bean.Address;
  3. import org.springframework.boot.context.properties.ConfigurationProperties;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. @Configuration
  7. public class AppConfig2 {
  8.     //  address 是第三方类,使用以下方式完成配置到属性的绑定
  9.     @Bean
  10.     @ConfigurationProperties(prefix = "other.abc")
  11.     public Address address() {
  12.         return new Address();
  13.     }
  14. }
复制代码
指定配置数据来源
  1. @Component
  2. @ConfigurationProperties(prefix = "app2.abc")
  3. // 指定配置数据来自/a/b/group-info.properties路径的配置文件
  4. @PropertySource("classpath:/a/b/group-info.properties")
  5. public class AppBean {
  6. ...
  7. }
复制代码
@ImportResource注解

当SpringBoot项目中出现ApplicationContext.xml文件。并且文件中配置了Bean。要把这个Bean注入到容器中。
  1. package com.ali.bindtobean.bean;
  2. public class Person {
  3.     private String name;
  4.     private int age;
  5.     public String getName() {
  6.         return name;
  7.     }
  8.     public void setName(String name) {
  9.         this.name = name;
  10.     }
  11.     public int getAge() {
  12.         return age;
  13.     }
  14.     public void setAge(int age) {
  15.         this.age = age;
  16.     }
  17.     @Override
  18.     public String toString() {
  19.         return super.toString();
  20.     }
  21. }
复制代码
配置文件如下:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
  5.     <bean id="person" >
  6.         <property name="name" value="jack"/>
  7.         <property name="age" value="20"/>
  8.     </bean>
  9. </beans>
复制代码
  1. // 在主入口程序添加以下注解让applocationContext.xml文件生效
  2. @ImportResource("classpath:/applocationContext.xml")
复制代码
Environment

spring提供的一个接口。SpringBoot启动的时候会把环境、系统信息封装到Environment对象中,需要获取这些信息,可使用Environment接口的方法。
Environment对象主要包括

  • 当前激活的配置文件 active-profiles
  • 系统属性,如系统名字 、java版本
  • 环境变量
  • 应用程序启动时传给主方法的命令行参数
  1. @Autowired
  2. private Environment environment;
  3. public void  doSomething() {
  4.     // 获取当前激活的配置文件
  5.     String[] activeProfiles = environment.getActiveProfiles();
  6.     for (String activeProfile : activeProfiles) {
  7.         System.out.println(activeProfile);
  8.     }
  9.     //  获取配置信息
  10.     String property = environment.getProperty("app.xyz.address.city");
  11.     System.out.println(property);
  12. }
复制代码
SpringBoot aop实现

添加依赖
  1. <dependency>
  2.     <groupId>org.springframework.boot</groupId>
  3.     spring-boot-starter-aop</artifactId>
  4.     <version>3.3.5</version>
  5. </dependency>
复制代码
编写切面类
  1. package com.ali.springaop.component;
  2. import org.aspectj.lang.JoinPoint;
  3. import org.aspectj.lang.annotation.Aspect;
  4. import org.aspectj.lang.annotation.Before;
  5. import org.aspectj.lang.annotation.Pointcut;
  6. import org.slf4j.LoggerFactory;
  7. import org.slf4j.Logger;
  8. import org.springframework.stereotype.Component;
  9. import java.util.Arrays;
  10. // 指定切面类
  11. @Aspect
  12. @Component
  13. public class LoggingAspect {
  14.     private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);
  15.     // 定义切入点,匹配所有以“service”结尾的包下的所有方法
  16.     @Pointcut("execution(* com.ali.springaop.service..*(..))")
  17.     public void ServiceMethods(){
  18.     }
  19.     // 前置通知,切入点的方法执行前执行此代码
  20.     @Before("ServiceMethods()")
  21.     public void before(JoinPoint joinPoint) {
  22.         String methodName = joinPoint.getSignature().getName();
  23.         Object[] args = joinPoint.getArgs();
  24.         logger.info("Method [{}] with parameters [{}] is called", methodName, Arrays.toString(args));
  25.     }
  26. }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

2026-1-24 07:11:03

举报

懂技术并乐意极积无私分享的人越来越少。珍惜
您需要登录后才可以回帖 登录 | 立即注册