Spring配置方式演进:从XML到注解,构建灵活高效的开发体系

news2025/4/13 5:05:36

Spring配置方式演进:从XML到注解,构建灵活高效的开发体系

在Spring框架的演进长河中,配置方式始终是开发者需要掌握的核心技能。从早期XML一统天下的严谨规范,到注解驱动的敏捷开发,再到如今Java Config的优雅实践,配置管理的变革折射出软件开发范式的革新。本文深入剖析XML与注解两种配置范式,既是对传统技术的系统性梳理,亦是对现代Spring生态的前瞻性探索。

文章以"配置维度"为经线,从Bean生命周期、依赖注入到AOP切面编程,层层拆解基础原理;以"实战场景"为纬线,通过多环境配置、条件化加载等企业级案例,对比不同方案的适用边界。特别设计的配置决策树与演进路线图,将帮助开发者在遗留系统改造与云原生架构建设中,精准选择适配的配置策略。

一、基础 Bean 管理

1.1 Bean 生命周期管理

XML 配置详解

<bean id="dataSource" class="com.DataSource" 
  init-method="init" 
  destroy-method="cleanup">
  <property name="poolSize" value="10"/>
</bean>
  • init-method:指定Bean初始化完成后调用的方法,用于资源准备
  • destroy-method:指定Bean销毁前调用的方法,用于资源清理
  • property:注入基本类型属性值,这里是设置连接池大小

注解配置详解

@Component
public class DataSource implements InitializingBean, DisposableBean {
    @Override
    public void afterPropertiesSet() {
        // 所有属性设置完成后执行
    }
    
    @Override
    public void destroy() {
        // Bean销毁时执行
    }
    
    @PreDestroy
    public void customDestroy() {
        // 另一种销毁方式,执行顺序在destroy()之后
    }
}
  • InitializingBean:接口方式实现初始化逻辑
  • DisposableBean:接口方式实现销毁逻辑
  • @PostConstruct/@PreDestroy:JSR-250标准注解,更灵活的生命周期控制

1.2 延迟初始化

XML 配置详解

<bean id="heavyResource" class="com.HeavyResource" lazy-init="true"/>
  • lazy-init:设置为true时,Bean在第一次被请求时才会初始化,而不是应用启动时

注解配置详解

@Lazy
@Component
public class HeavyResource {
    // 类级别延迟初始化
}
  • @Lazy:可以标注在类或@Bean方法上,实现延迟加载

二、依赖注入深入

2.1 多实现类注入

XML 配置详解

<bean id="wechatPay" class="com.payment.WechatPay"/>
<bean id="alipay" class="com.payment.Alipay"/>

<bean id="orderService" class="com.service.OrderService">
  <property name="paymentService" ref="alipay"/>
</bean>
  • ref:显式指定要注入的Bean名称
  • property:通过setter方法注入依赖

注解配置详解

@Service
public class OrderService {
    @Qualifier("wechatPay")
    @Autowired
    private PaymentService paymentService;
}
  • @Qualifier:当有多个同类型Bean时指定具体实现
  • @Autowired:自动按类型注入,可标注在字段、构造方法或setter方法上

2.2 复杂对象注入

XML 配置详解

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
  <property name="staticMethod" value="com.utils.DateUtil.setTimeZone"/>
  <property name="arguments">
    <list>
      <value>Asia/Shanghai</value>
    </list>
  </property>
</bean>
  • MethodInvokingFactoryBean:特殊Bean,用于调用静态方法
  • arguments:方法参数列表,支持复杂类型注入

注解配置详解

@Bean
public MethodInvokingFactoryBean configureTimeZone() {
    MethodInvokingFactoryBean bean = new MethodInvokingFactoryBean();
    bean.setStaticMethod("com.utils.DateUtil.setTimeZone");
    bean.setArguments(new Object[]{"Asia/Shanghai"});
    return bean;
}
  • @Bean方法:通过编程方式创建复杂Bean实例
  • 相比XML更类型安全,IDE支持更好

三、AOP 高级配置

3.1 切入点表达式进阶

XML 配置详解

<aop:pointcut id="daoMethods" 
  expression="execution(* com.dao.*.*(..)) && @annotation(com.annotations.Auditable)"/>
  • execution:匹配方法执行连接点
  • @annotation:限制只匹配带有特定注解的方法
  • &&:组合多个匹配条件

注解配置详解

@Pointcut("execution(* com.dao.*.*(..)) && @annotation(audit)")
public void auditableMethods(Auditable audit) {}

@Before("auditableMethods(audit)")
public void logAudit(Auditable audit) {
    // 可以访问注解参数
}
  • @Pointcut:定义可重用的切入点表达式
  • 注解参数绑定:可以将注解对象作为参数传递给通知方法

3.2 环绕通知实战

XML 配置详解

<aop:around method="timeMonitor" pointcut-ref="serviceMethods"/>
  • aop:around:声明环绕通知
  • pointcut-ref:引用已定义的切入点

注解配置详解

@Around("execution(* com.service.*.*(..))")
public Object timeMonitor(ProceedingJoinPoint joinPoint) throws Throwable {
    // 前置逻辑
    Object result = joinPoint.proceed(); // 执行目标方法
    // 后置逻辑
    return result;
}
  • ProceedingJoinPoint:提供访问目标方法的能力
  • 完全控制目标方法的执行时机和方式

四、条件化配置实战

4.1 基于属性的条件配置

XML 配置详解

<bean id="cacheService" class="com.cache.${cache.provider}"/>
  • ${}:属性占位符,从外部属性文件读取值

注解配置详解

@ConditionalOnProperty(name = "cache.enable", havingValue = "true")
public class CacheConfig {
    @ConditionalOnMissingBean
    public CacheService cacheService() {
        return new RedisCache();
    }
}
  • @ConditionalOnProperty:根据配置属性决定是否创建Bean
  • @ConditionalOnMissingBean:当容器中不存在指定类型的Bean时才创建

4.2 多环境邮件配置

XML 配置详解

<beans profile="dev">
  <bean id="mailSender" class="com.mail.MockMailSender"/>
</beans>
  • profile:定义特定环境下的配置

注解配置详解

@Profile("dev")
public MailSender mockMailSender() {
    return new MockMailSender();
}
  • @Profile:更简洁的环境隔离方式
  • 可与@Conditional组合实现复杂条件判断

五、扩展功能对比

5.1 国际化配置

XML 配置详解

<bean id="messageSource" class="ResourceBundleMessageSource">
  <property name="basenames" value="messages,errors"/>
</bean>
  • basenames:指定国际化资源文件基名

注解配置详解

@Bean
public MessageSource messageSource() {
    ResourceBundleMessageSource source = new ResourceBundleMessageSource();
    source.setBasenames("messages", "errors");
    return source;
}
  • 编程式配置更灵活,可以添加额外设置如编码格式

5.2 自定义 Bean 后处理器

XML 配置详解

<bean class="com.processor.CustomBeanPostProcessor"/>
  • 只需声明Bean,Spring会自动识别并应用

注解配置详解

@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // 可以修改或包装Bean实例
        return bean;
    }
}
  • 对容器中所有Bean生效
  • 常用于实现横切关注点如监控、代理等

六、企业级配置方案

6.1 数据源与事务管理

XML 配置详解

<tx:annotation-driven transaction-manager="txManager"/>
  • tx:annotation-driven:启用注解驱动的事务管理

注解配置详解

@EnableTransactionManagement
public class DataSourceConfig {
    @Bean
    public PlatformTransactionManager txManager() {
        return new DataSourceTransactionManager(dataSource());
    }
}
  • @EnableTransactionManagement:替代XML的事务配置
  • 支持更细粒度的配置选项

6.2 安全配置

XML 配置详解

<http auto-config="true">
  <intercept-url pattern="/admin/**" access="ROLE_ADMIN"/>
</http>
  • intercept-url:定义URL访问控制规则

注解配置详解

protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
      .antMatchers("/admin/**").hasRole("ADMIN");
}
  • 链式API更直观
  • 更好的类型安全和IDE支持

七、Java 配置最佳实践

@Configuration
@ComponentScan("com")
@EnableAspectJAutoProxy
@EnableTransactionManagement
public class AppConfig {
    // 集中管理所有Bean定义
}
  • @Configuration:标记为配置类
  • @ComponentScan:替代XML的context:component-scan
  • @EnableXXX:一站式启用各种Spring功能

配置选择建议

  1. 新项目:优先使用Java配置+注解
  2. 遗留系统:逐步将XML迁移到注解
  3. 第三方集成:XML配置可能更简单
  4. 复杂条件:使用@Conditional系列注解
  5. 环境差异:结合@Profile和属性文件

掌握这些配置方式的原理和适用场景,能够根据项目需求灵活选择最合适的配置方案。

八、决策树:选择配置方式的 5 个维度

维度XML 配置适用场景注解配置适用场景
项目规模大型传统项目微服务/新项目
配置灵活性需求需要动态修改固定配置
团队技术栈传统 JavaEE 背景熟悉 Spring 生态
第三方库集成老式库Spring Boot Starter
维护需求长期维护(混合配置)短期项目(纯注解)

附:Spring 配置演进史

版本配置方式特点
Spring 1.xXML 100%繁琐但统一
Spring 2.5引入 @Component 注解开启注解时代
Spring 3.0Java Config 支持可完全替代 XML
Spring 4.0@Conditional 条件配置为 Spring Boot 铺路
Spring Boot自动配置 + 约定优于配置配置工作量减少 70%

学习建议

  1. 从 XML 开始理解 Spring 核心机制
  2. 逐步过渡到注解配置
  3. 最终掌握 Java Config 最佳实践

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2333560.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于ImGui+FFmpeg实现播放器

基于ImGuiFFmpeg实现播放器 演示&#xff1a; ImGui播放器 继续研究FFmpeg&#xff0c;之前做了一个SDL的播放器&#xff0c;发现SDL的可视化UI界面的功能稍微差了点&#xff0c;所以今天我们换了一个新的工具&#xff0c;也就是ImGui。 ImGui官方文档&#xff1a;https://g…

python的web框架flask(hello,world版)

问题 最近需要基于一个开源项目进行二次开发&#xff0c;但是&#xff0c;现在的我主修java&#xff0c;从来没有接触过python的web开发。所以&#xff0c;我现在需要学习一下flask的hello&#xff0c;world。 python版本选择 通过这个Python版本状态页面Status of Python v…

Java面试39-Zookeeper中的Watch机制的原理

Zookeeper是一个分布式协调组件&#xff0c;为分布式架构下的多个应用组件提供了顺序访问控制能力。它的数据存储采用了类似于文件系统的树形结构&#xff0c;以节点的方式来管理存储在Zookeeper上的数据。 Zookeeper提供了一个Watch机制&#xff0c;可以让客户端感知到Zooke…

同时打开多个Microchip MPLAB X IDE

0.引用 Microchip 32位MCU CAN驱动图文教程-附源码 - 哔哩哔哩 https://bbs.21ic.com/icview-3391426-1-1.html https://bbs.21ic.com/icview-3393632-1-1.html 1.前言 工作中接触到使用Microchip 的 MPLAB X IDE 开发工具&#xff0c;使用的MCU是Microchip SAMD21J18A MCU…

达梦数据库使用druid提示:dbType not support : dm

简单处理&#xff1a; 移除wall即可 &#xff08;但是用druid那都希望能用上它的功能的&#xff0c;不然为什么不用其他没带检查的jdbc呢。&#xff09; 中等复杂处理&#xff1a; druid 是阿里开源的项目&#xff0c;所以去github上找对应版本的源码下载&#xff1a;https:/…

[定位器]晶艺LA1823,4.5V~100V, 3.5A,替换MP9487,MP9486A,启烨科技

Features  4.5V to 100V Wide Input Range  3.5A Typical Peak Current Limit  Integrated 500mΩ low resistance high side power MOS.  Constant On Time Control with Constant Switching Frequency.  180μA Low Quiescent Current  150kHz/240kHz/420kHz Swi…

难度偏低,25西电人工智能学院821、833、834考研录取情况

1、人工智能学院各个方向 2、人工智能学院近三年复试分数线对比 学长、学姐分析 由表可看出&#xff1a; 1、智能院25年院线相对于24年院线 全部专业下降比较多&#xff0c;其中控制科学与工程下降20分&#xff0c;计算机科学与技术下降20分&#xff0c;计算机技术[专硕]下降…

使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第七讲)

这一期来讲解与文本框配套使用的键盘&#xff0c;以及键盘如何在项目中开启。 打开GUI_guider软件平台&#xff0c;在左上角点开工程选项&#xff0c;在该栏目的最下方点击系统设置。 随后在系统设置界面中点击项目选项&#xff0c;选择显示键盘。 在该界面中可以设置键盘文字…

通过AWS EKS 生成并部署容器化应用

今天给大家分享一个实战例子&#xff0c;如何在EKS上创建容器化应用并通过ALB来发布。先介绍一下几个基本概念&#xff1a; IAM, OpenID Connect (OIDC) 2014 年&#xff0c;AWS Identity and Access Management 增加了使用 OpenID Connect (OIDC) 的联合身份支持。此功能允许…

nginx入门,部署静态资源,反向代理,负载均衡使用

Nginx在linux上部署静态资源 概念介绍 Nginx可以作为静态web服务器来部署静态资源。这里所说的静态资源是指在服务端真实存在&#xff0c;并且能够直接展示的一些文件&#xff0c;比如常见的html页面、css文件、js文件、图片、视频等资源。 相对于Tomcat&#xff0c;Nginx处理…

智膳优选 | AI赋能的智慧食堂管理专家 —— 基于飞书多维表格和扣子(Coze)的智能解决方案

智膳优选 | AI赋能的智慧食堂管理专家 基于飞书多维表格和扣子&#xff08;Coze&#xff09;的智能解决方案 数据驱动餐饮管理&#xff0c;让每一餐都是营养与经济的完美平衡&#xff01; “智膳优选”通过整合飞书与Coze&#xff0c;将数据智能引入校园餐饮管理&#xff0…

最新的es版本忘记密码,重置密码

刚刚安装了最新的es版本,就忘了密码,怎么重置密码呢? 一、进入es的斌目录 #进入es文件/bin 目录 ./elasticsearch-reset-password -u elastic 二 、输入对应的密码 然后再次访问 我的是去掉了ssl的访问 三、如果报错:解决 [main] WARN

Compose Multiplatform+Kotlin Multiplatfrom 第五弹跨平台 截图

截图功能 Compose MultiplatformKotlin Multiplatfrom下实现桌面端的截图功能&#xff0c;起码搞了两星期&#xff0c;最后终于做出来了&#xff0c;操作都很流畅&#xff0c;截取的文件大小也正常&#xff0c;可参考支持讨论&#xff01; 功能效果 代码实现 //在jvmMain下创…

Elasticearch数据流向

Elasticearch数据流向 数据流向图 --- config: layout: elk look: classic theme: mc --- flowchart LR subgraph s1["图例"] direction TB W["写入流程"] R["读取流程"] end A["Logstash Pipeline"] -- 写入请求 --> B["Elas…

在docker里装rocketmq-console

首先要到github下载&#xff08;这个一般是需要你有梯子&#xff09; GitHub - apache/rocketmq-externals at release-rocketmq-console-1.0.0 如果没有梯子&#xff0c;用下面这个百度网盘链接下 http://链接: https://pan.baidu.com/s/1x8WQVmaOBjTjss-3g01UPQ 提取码: fu…

使用Python写入JSON、XML和YAML数据到Excel文件

在当今数据驱动的技术生态中&#xff0c;JSON、XML和YAML作为主流结构化数据格式&#xff0c;因其层次化表达能力和跨平台兼容性&#xff0c;已成为系统间数据交换的通用载体。然而&#xff0c;当需要将这类半结构化数据转化为具备直观可视化、动态计算和协作共享特性的载体时&…

x-cmd install | Slumber - 告别繁琐,拥抱高效的终端 HTTP 客户端

目录 核心优势&#xff0c;一览无遗安装应用场景&#xff0c;无限可能示例告别 GUI&#xff0c;拥抱终端 还在为调试 API 接口&#xff0c;发送 HTTP 请求而苦恼吗&#xff1f;还在各种 GUI 工具之间切换&#xff0c;只为了发送一个简单的请求吗&#xff1f;现在&#xff0c;有…

apijson 快速上手

apijson是强大的工具&#xff0c;简化了CRUD的操作&#xff0c;只要有数据库表&#xff0c;就能自动生成RESTFUL接口。但初次上手也是摸索了很长时间&#xff0c;尤其是部署与使用上&#xff0c;这里尝试以初学者角度来说下&#xff1a; 一、好处 1、对于简单的应用&#xff…

3D激光轮廓仪知识整理

文章目录 1.原理和应用场景1.1 相机原理1.1.1 测量原理1.1.2 相机激光器1.1.3 沙姆镜头1.1.4 相机标定1.1.5 中心线提取 1.2 应用场景1.2.1 测量相关应用1.2.2 缺陷检测相关应用 2.相机参数介绍及选型介绍2.1 成像原理2.2 原始图成像2.3 生成轮廓图2.4 相机规格参数2.4.1 单轮廓…

Stable Diffusion+Pyqt5: 实现图像生成与管理界面(带保存 + 历史记录 + 删除功能)——我的实验记录(结尾附系统效果图)

目录 &#x1f9e0; 前言 &#x1f9fe; 我的需求 &#x1f527; 实现过程&#xff08;按功能一步步来&#xff09; &#x1f6b6;‍♂️ Step 1&#xff1a;基本图像生成界面 &#x1f5c3;️ Step 2&#xff1a;保存图片并显示历史记录 &#x1f4cf; Step 3&#xff1a…