跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Spring属性注入
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{DISPLAYTITLE:Spring属性注入}} == 概述 == '''Spring属性注入'''(Property Injection)是[[Spring IoC容器]]实现依赖注入(DI)的核心机制之一,指通过外部配置(XML/注解/JavaConfig)为Bean对象的成员变量动态赋值的过程。与构造器注入并列,是Spring解耦组件关系的两大主要方式。 属性注入的核心特点: * 通过setter方法或字段直接赋值 * 支持简单类型(String/int等)和复杂对象(其他Bean) * 运行时由容器自动完成依赖装配 * 符合"好莱坞原则"(不要调用我们,我们会调用你) == 注入方式 == === 1. XML配置注入 === 最传统的注入方式,通过<code><property></code>标签指定: <syntaxhighlight lang="xml"> <!-- applicationContext.xml --> <bean id="dataSource" class="com.example.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mydb"/> <property name="username" value="root"/> <property name="password" value="secret"/> </bean> </syntaxhighlight> 等效的Java类定义: <syntaxhighlight lang="java"> public class BasicDataSource { private String driverClassName; private String url; private String username; private String password; // Setter方法必须存在 public void setDriverClassName(String driver) { this.driverClassName = driver; } // 其他setter... } </syntaxhighlight> === 2. 注解注入 === Spring 2.5+支持的现代方式: <syntaxhighlight lang="java"> @Component public class OrderService { @Value("${order.max.retry}") // 注入配置值 private int maxRetry; @Autowired // 按类型自动装配 private PaymentGateway gateway; @Resource(name="emailService") // 按名称装配 private NotificationService notifier; } </syntaxhighlight> 需配合注解扫描: <syntaxhighlight lang="xml"> <context:component-scan base-package="com.example"/> <context:property-placeholder location="classpath:app.properties"/> </syntaxhighlight> === 3. JavaConfig注入 === Spring 3.0+的纯Java配置方式: <syntaxhighlight lang="java"> @Configuration public class AppConfig { @Bean public DataSource dataSource() { BasicDataSource ds = new BasicDataSource(); ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUrl("jdbc:mysql://localhost:3306/mydb"); return ds; } } </syntaxhighlight> == 注入类型 == <mermaid> pie title 属性注入类型占比 "简单值" : 35 "Bean引用" : 45 "集合类型" : 20 </mermaid> === 1. 简单值注入 === 支持所有基本类型及其包装类、String、Class等: <syntaxhighlight lang="xml"> <property name="timeout" value="5000"/> <!-- 自动转换为int --> <property name="active" value="true"/> <!-- boolean --> </syntaxhighlight> === 2. Bean引用注入 === 注入容器中的其他Bean: <syntaxhighlight lang="xml"> <bean id="userService" class="com.example.UserService"> <property name="userDao" ref="jdbcUserDao"/> <!-- ref指向其他bean --> </bean> </syntaxhighlight> === 3. 集合类型注入 === 复杂集合的配置示例: <syntaxhighlight lang="xml"> <bean id="complexBean" class="com.example.CollectionBean"> <property name="list"> <list> <value>item1</value> <ref bean="specialService"/> </list> </property> <property name="map"> <map> <entry key="config1" value="100"/> <entry key="service" value-ref="logService"/> </map> </property> </bean> </syntaxhighlight> == 高级特性 == === 延迟注入 === 使用<code>@Lazy</code>注解延迟初始化: <syntaxhighlight lang="java"> @Component public class HeavyResource { @Lazy @Autowired private ExpensiveToLoad externalService; } </syntaxhighlight> === 条件注入 === Spring 4.0+的条件化装配: <syntaxhighlight lang="java"> @Bean @Conditional(ProdEnvCondition.class) public DataSource productionDataSource() { // 仅当条件满足时创建Bean } </syntaxhighlight> === SpEL表达式 === 使用Spring表达式语言动态计算值: <syntaxhighlight lang="xml"> <property name="defaultLocale" value="#{systemProperties['user.language']}"/> <property name="randomNumber" value="#{T(java.lang.Math).random() * 100}"/> </syntaxhighlight> == 最佳实践 == 1. '''强制依赖'''推荐使用构造器注入,可选依赖使用属性注入 2. 避免混合使用多种注入方式(如同时使用XML和注解) 3. 对<code>@Autowired</code>添加<code>@Qualifier</code>消除歧义 4. 优先使用类型安全(type-safe)的JavaConfig方式 == 典型应用场景 == '''电商系统库存服务示例''': <syntaxhighlight lang="java"> @Service public class InventoryService { @Value("${inventory.threshold}") private int stockThreshold; @Autowired private WarehouseLocator locator; @Resource private List<InventoryValidator> validators; // 业务方法... } </syntaxhighlight> * <code>stockThreshold</code>:从配置文件中注入 * <code>locator</code>:自动装配主要仓库定位器 * <code>validators</code>:收集所有实现<code>InventoryValidator</code>接口的Bean == 常见问题 == {{Warning|1=循环依赖问题:}} 当BeanA依赖BeanB,同时BeanB又依赖BeanA时,解决方案: * 重构代码消除循环依赖 * 使用<code>@Lazy</code>延迟初始化 * 改用setter注入(而非构造器注入) {{Note|1=注入vs直接new对象的区别:}} <math> \begin{array}{|c|c|} \hline \text{属性注入} & \text{直接实例化} \\ \hline \text{由容器控制生命周期} & \text{开发者手动管理} \\ \hline \text{易于配置修改} & \text{需重新编译} \\ \hline \text{支持AOP等高级特性} & \text{无容器服务} \\ \hline \end{array} </math> == 总结 == Spring属性注入机制提供了灵活的依赖配置方式,通过本文介绍的多种实现形式和最佳实践,开发者可以构建松耦合、易测试的应用程序。随着Spring版本的演进,推荐逐步采用类型安全的JavaConfig结合注解的方式,以获得更好的开发体验和代码可维护性。 [[Category:后端框架]] [[Category:Spring]] [[Category:Spring Ioc容器]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
该页面使用的模板:
模板:Mbox
(
编辑
)
模板:Note
(
编辑
)
模板:Warning
(
编辑
)
模块:Arguments
(
编辑
)
模块:Message box
(
编辑
)
模块:Message box/ambox.css
(
编辑
)
模块:Message box/configuration
(
编辑
)
模块:Yesno
(
编辑
)