spring基于xml注入bean的几种方式
作者:百科 来源:时尚 浏览: 【大 中 小】 发布时间:2026-10-17 06:16:15 评论数:
Spring基于XML注入Bean的几种方式
用XML配置Spring的那套东西,现在虽然被注解和Java Config抢了不少风头,注种方但老项目里翻一翻,基于满屏的注种方<bean>标签还是家常便饭。搞懂这几种注入方式,基于改起遗留代码来至少不会手忙脚乱。注种方
属性注入:最眼熟的基于那种
属性注入靠的是setter方法。写起来直白——先给类留个无参构造,注种方然后每个字段配一个set方法。基于XML里用<property>标签,注种方name写字段名,基于value或ref填值。注种方
<bean id="userService" class="com.example.UserService"> <property name="userDao" ref="userDao"/> <property name="maxRetry" value="3"/> </bean> 这种写法灵活,基于字段想设就设,注种方不设也有默认值兜着。基于但问题也在这儿——对象构造完之后还能被改,依赖关系不是强约束。Spring官方文档早些年推荐构造器注入,后来又说属性注入也行,来回摇摆过几次。实际项目里,属性注入的代码量最少,维护起来反而最省心,所以至今仍然是主流。
构造器注入:把依赖钉死
构造器注入要求类提供一个带参构造,参数就是依赖项。XML里用<constructor-arg>,可以按索引、类型或参数名来匹配。
<bean id="orderService" class="com.example.OrderService"> <constructor-arg index="0" ref="paymentGateway"/> <constructor-arg index="1" value="true"/> </bean> 好处是对象一旦创建,依赖就固定了,不可能出现半初始化状态。循环依赖在这种模式下会直接报错,逼着你去重构代码结构。坏处也明显——参数一多,XML就变得又长又难读,index顺序改一下就得同步改配置,容易出错。我见过一个类有七个构造参数的,XML里密密麻麻全是constructor-arg,那画面不太美好。
工厂方法注入:绕个弯儿创建对象
有时候Bean不是直接new出来的,得走工厂。静态工厂用factory-method,实例工厂还得先配一个工厂Bean,再用factory-bean指向它。
<bean id="dataSource" class="com.example.DataSourceFactory" factory-method="create"> <constructor-arg value="jdbc:mysql://localhost:3306/test"/> </bean> 这种场景在整合第三方库时特别常见,比如某些连接池或者复杂对象的构建。XML配置在这里的优势是能把创建逻辑和业务类解耦,改工厂方法不用动Java代码。但缺点也摆着——调试的时候得多跳几层,看堆栈都得愣一下。
内部Bean和级联属性:省个id但别滥用
如果一个Bean只给某个属性用,可以写成内部Bean,不配id,直接嵌在<property>里。
<bean id="outer" class="com.example.Outer"> <property name="inner"> <bean class="com.example.Inner"/> </property> </bean> 这招能减少XML里的顶层Bean数量,但内部Bean没法被其他Bean引用,复用性为零。级联属性更微妙,比如<property name="dao.dataSource" ref="ds"/>,要求dao不能是null,否则直接抛异常。这种写法看着简洁,实际维护时容易踩坑,我一般能不用就不用。
集合注入:List、Set、Map一个不落
集合类型的注入用<list>、<set>、<map>、<props>标签,写起来啰嗦但语义清晰。
<property name="handlers"> <list> <ref bean="handlerA"/> <ref bean="handlerB"/> </list> </property> 合并集合可以用<merge>,不过实际项目里我几乎没见人用过。大多数时候就是老老实实列出来,反正IDE有提示,写起来也不算太痛苦。
p命名空间:少写几行但可读性打折
Spring 2.5之后引入了p命名空间,把属性注入压成一行:
<bean id="userService" class="com.example.UserService" p:userDao-ref="userDao" p:maxRetry="3"/> XML体积能小不少,但-ref后缀和普通value混在一起,看久了眼花。团队里如果没人统一风格,有人用p有人用<property>,代码审查的时候能吵起来。我的态度是:老项目保持原样,新项目直接上注解或Java Config,别在XML上继续雕花了。
这几种方式没有绝对的好坏,全看项目上下文。XML配置的啰嗦是事实,但它的集中管理和不侵入代码的特性,在某些场景下依然有价值。改老代码的时候,能认出这些写法、知道它们各自的行为边界,比争论哪种更好要实在得多。
```