Spring依赖注入
Spring依赖注入
构造器注入
构造器注入需要有带参数的构造方法
在xml中只需在<bean>标签内加上<constructor-arg>标签
其中:
- name指的是这个属性的名字(实际上是构造方法中的参数名)
- value是这个属性的值可以用来对基本类型和String类型进行赋值
- ref 如果属性的类型是复杂对象的引用类型,可以用ref引用其他bean标签
public class TestProxyServiceImpl implements TestProxyService {
private User user;
private String name;
public TestProxyServiceImpl(User user,String name) {
this.user = user;
this.name = name;
}
@Override
public void sayhello() {
System.out.println("hello" + user+","+name);
}
}
<bean id="user" class="com.mb.msgboards.vo.User"/>
<bean id="proxyService" class="com.mb.msgboards.service.impl.TestProxyServiceImpl">
<constructor-arg name="user" ref="user"/>
<constructor-arg name="name" value="myname"/>
</bean>
这种指定name来注入属性的方式显得有些耦合 ,name中指定的其实是构造方法的参数名,这可能会和属性名不一致,如果参数名被修改,那么对应的配置也要修改,耦合度太高
于是有了以下方案:
<bean id="user" class="com.mb.msgboards.vo.User"/>
<bean id="proxyService" class="com.mb.msgboards.service.impl.TestProxyServiceImpl">
<constructor-arg type="com.mb.msgboards.vo.User" ref="user"/>
<constructor-arg type="java.lang.String" name="name" value="myname"/>
</bean>
通过指定类型来对属性进行注入,可以自动匹配属性类型,但是对于多个相同类型的属性,这种也无法指定唯一确定的属性,于是又有了下面这种方式:
<bean id="user" class="com.mb.msgboards.vo.User"/>
<bean id="proxyService" class="com.mb.msgboards.service.impl.TestProxyServiceImpl">
<constructor-arg index="0" ref="user"/>
<constructor-arg index="1" value="myname"/>
</bean>
直接通过指定构造方法的参数数序来进行匹配注入,这种方式可以避免属性名或参数名的修改导致配置失效的问题,也避免了类型相同导致的无法确定唯一属性的问题
构造器注入还有个好处是:对于构造器参数中的属性,一定不会漏掉配置,如果漏配置会xml文件会报错,相较于setter注入更严谨
Setter注入
setter注入时类中必须要有对这个属性的setter方法
public class TestProxyServiceImpl implements TestProxyService {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
public void sayhello() {
System.out.println("hello" + name);
}
}
<bean id="proxyService1" class="com.mb.msgboards.service.impl.TestProxyServiceImpl">
<property name="name" value="zzz"/>
</bean>
在xml中只需在<bean>标签内加上<property>标签
其中:
- name指的是这个属性的名字(实际上是set方法名中set后的字符串)
- value是这个属性的值可以用来对基本类型和String类型进行赋值
- ref 如果属性的类型是复杂对象的引用类型,可以用ref引用其他bean标签
引用类型例子:
<bean id="user" class="com.mb.msgboards.vo.User"/>
<bean id="proxyService" class="com.mb.msgboards.service.impl.TestProxyServiceImpl">
<property name="user" ref="user"/>
</bean>
public class TestProxyServiceImpl implements TestProxyService {
private User user;
public void setUser(User user) {
this.user = user;
}
@Override
public void sayhello() {
System.out.println("hello" + user);
}
}
setter注入的方式是可选注入,如果类中存在不能为null的属性,建议使用构造器注入,setter注入方式可能会导致属性为null,因为setter不是必须,可能会漏掉配置
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)