Spring5深入浅出篇:Spring对象属性注入详解

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
函数计算FC,每月15万CU 3个月
可观测可视化 Grafana 版,10个用户账号 1个月
简介: Spring5深入浅出篇:Spring对象属性注入详解

Spring5深入浅出篇:Spring对象属性注入详解

首先需要了解什么是注入?在创建对象的过程中,不仅仅是创建一个对象还需要为对象的属性赋值.这一系列操作在Spring中,是通过Spring工厂以及配置文件,为所创建的对象的成员变量赋值.

为Spring的对象属性赋值

这里直接上代码

ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
       Person person = (Person) ctx.getBean("person");
       person.setId(1);  //通过代码为成员变量赋值,存在耦合
       person.setName("suns");
       System.out.println("person = " + person);

Spring的注入(开发步骤)

  • 类的成员变量提供set get⽅法
  • 配置spring的配置⽂件
<bean id="person" class="com.baizhiedu.basic.Person">
 <property name="id">
 <value>10</value>
 </property>
 <property name="name">
 <value>xiaojr</value>
 </property>
</bean>

简单来说,这样的注入方式主要就是为了解耦合

Spring注⼊的原理分析(简易版)

Spring通过底层调⽤对象属性对应的set⽅法,完成成员变量的赋值,这种⽅式我们也称之为set注⼊

Set注⼊详解

针对于不同类型的成员变量,在<property>标签,需要嵌套其他标签
<property>
 xxxxx
</property>

JDK内置类型

String+8种基本类型

<value>suns</value>

数组

<list>
 <value>suns@zparkhr.com.cn</value>
 <value>liucy@zparkhr.com.cn</value>
 <value>chenyn@zparkhr.com.cn</value>
</list>

Set集合

<set>
 <value>11111</value>
 <value>112222</value>
</set>
<set>
 <ref bean
 <set
</set>

List集合

<list>
 <value>11111</value>
 <value>2222</value>
</list>
<list>
 <ref bean
 <set
</list>

Map集合

注意: map -- entry -- key有特定的标签 <key></key>
 值根据对应类型选择对应类型的标签
<map>
 <entry>
 <key><value>suns</value></key>
 <value>3434334343</value>
 </entry>
 <entry>
 <key><value>chenyn</value></key>
 <ref bean
 </entry>
</map>

Properites

Properties类型 特殊的Map key=String value=String

<props>
 <prop key="key1">value1</prop>
 <prop key="key2">value2</prop>
</props>

复杂的JDK类型 (Date)

需要程序员⾃定义类型转换器,处理。

⽤户⾃定义类型

第⼀种⽅式

  • 为成员变量提供set get⽅法
  • 配置⽂件中进⾏注⼊(赋值)
<bean id="userService" class="xxxx.UserServiceImpl">
 <property name="userDAO">
 <bean class="xxx.UserDAOImpl"/>
 </property>
</bean>

第二种⽅式

  • 第⼀种赋值⽅式存在的问题
1. 配置⽂件代码冗余
2. 被注⼊的对象(UserDAO),多次创建,浪费(JVM)内存资源
  • 为成员变量提供set get⽅法
  • 配置⽂件中进⾏配置
<bean id="userDAO" class="xxx.UserDAOImpl"/>
<bean id="userService" class="xxx.UserServiceImpl">
 <property name="userDAO">
 <ref bean="userDAO"/>
 </property>
</bean>
#Spring4.x 废除了 <ref local=""/> 基本等效 <ref bean=""/>

Set注⼊的简化写法

基于属性简化

JDK类型注⼊
<property name="name">
 <value>suns</value>
</property>
<property name="name" value="suns"/>
注意:value属性 只能简化 8种基本类型+String 注⼊标签
⽤户⾃定义类型
<property name="userDAO">
 <ref bean="userDAO"/>
</property>
<property name="userDAO" ref="userDAO"/>

基于p命名空间简化

JDK类型注⼊
<bean id="person" class="xxxx.Person">
 <property name="name">
 <value>suns</value>
 </property>
</bean>
<bean id="person" class="xxx.Person" p:name="suns"/>
注意:value属性 只能简化 8种基本类型+String 注⼊标签
⽤户⾃定义类型
<bean id="userService" class="xx.UserServiceImpl">
 <property name="userDAO">
 <ref bean="userDAO"/>
</property>
</bean>
<bean id="userService" class="xxx.UserServiceImpl" p:userDAOref="userDAO"/>

构造注⼊

注⼊:通过Spring的配置⽂件,为成员变量赋值
Set注⼊:Spring调⽤Set⽅法 通过配置⽂件 为成员变量赋值
构造注⼊:Spring调⽤构造⽅法 通过配置⽂件 为成员变量赋值
  • 提供有参构造⽅法
public class Customer implements Serializable {
 private String name;
 private int age;
 public Customer(String name, int age) {
 this.name = name;
 this.age = age;
 }
}
  • Spring的配置⽂件
<bean id="customer"
class="com.baizhiedu.basic.constructer.Customer">
 <constructor-arg>
 <value>suns</value>
 </constructor-arg>
 <constructor-arg>
 <value>102</value>
 </constructor-arg>
</bean>

构造⽅法重载

参数个数不同时通过控制标签的数量进⾏区分

构造参数个数相同时通过在标签引⼊ type属性 进⾏类型的区分

注⼊的总结

未来的实战中,应⽤set注⼊还是构造注⼊?
答案:set注⼊更多
 1. 构造注⼊麻烦 (重载)
 2. Spring框架底层 ⼤量应⽤了 set注⼊

相关文章
|
12天前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
|
24天前
|
Java 测试技术 程序员
为什么Spring不推荐@Autowired用于字段注入?
作为Java程序员,Spring框架在日常开发中使用频繁,其依赖注入机制带来了极大的便利。然而,尽管@Autowired注解简化了依赖注入,Spring官方却不推荐在字段上使用它。本文将探讨字段注入的现状及其存在的问题,如难以进行单元测试、违反单一职责原则及易引发NPE等,并介绍为何Spring推荐构造器注入,包括增强代码可读性和维护性、方便单元测试以及避免NPE等问题。通过示例代码展示如何将字段注入重构为构造器注入,提高代码质量。
|
3月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
27天前
|
Java Spring
获取spring工厂中bean对象的两种方式
获取spring工厂中bean对象的两种方式
23 1
|
28天前
|
前端开发 Java Spring
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
91 2
|
28天前
|
缓存 Java Spring
源码解读:Spring如何解决构造器注入的循环依赖?
本文详细探讨了Spring框架中的循环依赖问题,包括构造器注入和字段注入两种情况,并重点分析了构造器注入循环依赖的解决方案。文章通过具体示例展示了循环依赖的错误信息及常见场景,提出了三种解决方法:重构代码、使用字段依赖注入以及使用`@Lazy`注解。其中,`@Lazy`注解通过延迟初始化和动态代理机制有效解决了循环依赖问题。作者建议优先使用`@Lazy`注解,并提供了详细的源码解析和调试截图,帮助读者深入理解其实现机制。
19 1
|
30天前
|
存储 Java 程序员
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
本文详细讲解了Spring框架中IOC容器如何存储和取出Bean对象,包括五大类注解(@Controller、@Service、@Repository、@Component、@Configuration)和方法注解@Bean的用法,以及DI(依赖注入)的三种注入方式:属性注入、构造方法注入和Setter注入,并分析了它们的优缺点。
20 0
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
|
3月前
|
缓存 Java 数据库连接
Spring Boot 资源文件属性配置,紧跟技术热点,为你的应用注入灵动活力!
【8月更文挑战第29天】在Spring Boot开发中,资源文件属性配置至关重要,它让开发者能灵活定制应用行为而不改动代码,极大提升了可维护性和扩展性。Spring Boot支持多种配置文件类型,如`application.properties`和`application.yml`,分别位于项目的resources目录下。`.properties`文件采用键值对形式,而`yml`文件则具有更清晰的层次结构,适合复杂配置。此外,Spring Boot还支持占位符引用和其他外部来源的属性值,便于不同环境下覆盖默认配置。通过合理配置,应用能快速适应各种环境与需求变化。
43 0
|
3月前
|
安全 Java 开发者
开发者必看!@Resource与private final的较量,Spring Boot注入技巧大揭秘,你不可不知的细节!
【8月更文挑战第29天】Spring Boot作为热门Java框架,其依赖注入机制备受关注。本文通过对比@Resource(JSR-250规范)和@Autowired(Spring特有),并结合private final声明的字段注入,详细探讨了两者的区别与应用场景。通过示例代码展示了@Resource按名称注入及@Autowired按类型注入的特点,并分析了它们在注入时机、依赖性、线程安全性和单一职责原则方面的差异,帮助开发者根据具体需求选择最合适的注入策略。
90 0
|
3月前
|
安全 Java C#
Spring创建的单例对象,存在线程安全问题吗?
Spring框架提供了多种Bean作用域,包括单例(Singleton)、原型(Prototype)、请求(Request)、会话(Session)、全局会话(GlobalSession)等。单例是默认作用域,保证每个Spring容器中只有一个Bean实例;原型作用域则每次请求都会创建一个新的Bean实例;请求和会话作用域分别与HTTP请求和会话绑定,在Web应用中有效。 单例Bean在多线程环境中可能面临线程安全问题,Spring容器虽然确保Bean的创建过程是线程安全的,但Bean的使用安全性需开发者自行保证。保持Bean无状态是最简单的线程安全策略;