• 作者简介:大家好,我是五度鱼,一个普通的Java领域博主,不停输出Java技术博客和干货。

  • 座右铭:锲而不舍,金石可镂。

  • 个人主页:五度鱼学Java的主页

文章目录

  • 前言
  • 1. set注入
  • 2. 构造注入
  • 3. p命名空间注入
  • 4. c命名空间注入

前言

  这几天学了Spring6,感觉到了Spring的强大和便捷。其中的IOC设计原则对对象的处理真的是达到了出神入化的地步,省去了不停的创建对象的过程。写此篇文章是为了总结一下IOC的四种属性注入方式,也是为了以后可以翻看,每日温习一遍,孔子说过:“温故而知新,可以为师矣”。各位朋友们在浏览此篇博客时可以温习一下IOC的知识。


1. set注入

  set注入是基于set方法注入的,它的底层是通过反射机制调用属性对应的set方法给属性赋值,这种方式必须要求属性对外提供set方法,让两个对象之间产生关系。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.powernode</groupId><artifactId>spring6-002-dependency-injection</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><repositories><repository><id>repository.spring.milestone</id><name>Spring Milestone Repository</name><url>https://repo.spring.io/milestone</url></repository></repositories><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.0-M2</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target></properties></project>
package com.powernode.spring6.dao;/*** @author 五度鱼* @version 1.0* @className UserDao* @since 1.0**/
public class UserDao {public void insert(){System.out.println("正在保存用户数据。");}
}
package com.powernode.spring6.service;import com.powernode.spring6.dao.UserDao;/*** @author 五度鱼* @version 1.0* @className UserService* @since 1.0**/
public class UserService {private UserDao userDao;// 使用set方式注入,必须提供set方法。// 反射机制要调用这个方法给属性赋值的。public void setUserDao(UserDao userDao) {this.userDao = userDao;}public void save(){userDao.insert();}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/><bean id="userServiceBean" class="com.powernode.spring6.service.UserService"><property name="userDao" ref="userDaoBean"/></bean></beans>
package com.powernode.spring6.test;import com.powernode.spring6.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** @author 五度鱼* @version 1.0* @className DITest* @since 1.0**/
public class DITest {@Testpublic void testSetDI(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");UserService userService = applicationContext.getBean("userServiceBean", UserService.class);userService.save();}
}

运行结果:

实现原理:

  • <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/><bean id="userServiceBean" class="com.powernode.spring6.service.UserService"><property name="userDao" ref="userDaoBean"/></bean></beans>
    
  • 通过property标签获取到属性名:userDao

    通过属性名推断出set方法名:setUserDao

    通过反射机制调用setUserDao()方法给属性赋值

    property标签的name是属性名。

    property标签的ref是要注入的bean对象的id

    (通过ref属性来完成bean的装配,这是bean最简单的一种装配方式。装配指的是:创建系统组件之间关联的动作)

    (1)setUsername() 演变为 username

    (2)setPassword() 演变为 password

    (3)setUserDao() 演变为 userDao

    (4)setUserService() 演变为 userService

2. 构造注入

核心原理:通过调用构造方法来给属性赋值。

package com.powernode.spring6.dao;/*** @author 五度鱼* @version 1.0* @className OrderDao* @since 1.0**/
public class OrderDao {public void deleteById(){System.out.println("正在删除订单。。。");}
}
package com.powernode.spring6.service;import com.powernode.spring6.dao.OrderDao;/*** @author 五度鱼* @version 1.0* @className OrderService* @since 1.0**/
public class OrderService {private OrderDao orderDao;// 通过反射机制调用构造方法给属性赋值public OrderService(OrderDao orderDao) {this.orderDao = orderDao;}public void delete(){orderDao.deleteById();}
}
<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/>
<bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService"><!--index="0"表示构造方法的第一个参数,将orderDaoBean对象传递给构造方法的第一个参数。--><constructor-arg index="0" ref="orderDaoBean"/>
</bean>
@Test
public void testConstructorDI(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");OrderService orderServiceBean = applicationContext.getBean("orderServiceBean", OrderService.class);orderServiceBean.delete();
}

运行结果如下:

如果构造方法有两个参数:

package com.powernode.spring6.service;import com.powernode.spring6.dao.OrderDao;
import com.powernode.spring6.dao.UserDao;/*** @author 五度鱼* @version 1.0* @className OrderService* @since 1.0**/
public class OrderService {private OrderDao orderDao;private UserDao userDao;// 通过反射机制调用构造方法给属性赋值public OrderService(OrderDao orderDao, UserDao userDao) {this.orderDao = orderDao;this.userDao = userDao;}public void delete(){orderDao.deleteById();userDao.insert();}
}

Spring配置文件:

<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/><bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService"><!--第一个参数下标是0--><constructor-arg index="0" ref="orderDaoBean"/><!--第二个参数下标是1--><constructor-arg index="1" ref="userDaoBean"/>
</bean><bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>

执行测试程序:

不使用参数下标,使用参数的名字可以吗?

<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/><bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService"><!--这里使用了构造方法上参数的名字--><constructor-arg name="orderDao" ref="orderDaoBean"/><constructor-arg name="userDao" ref="userDaoBean"/>
</bean><bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>

执行测试程序:

不指定参数下标,不指定参数名字,可以吗?

<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/>
<bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService"><!--没有指定下标,也没有指定参数名字--><constructor-arg ref="orderDaoBean"/><constructor-arg ref="userDaoBean"/>
</bean><bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>

执行测试程序:

配置文件中构造方法参数的类型顺序和构造方法参数的类型顺序不一致呢?

<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/><bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService"><!--顺序已经和构造方法的参数顺序不同了--><constructor-arg ref="userDaoBean"/><constructor-arg ref="orderDaoBean"/>
</bean><bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>

执行测试程序:

通过测试得知,通过构造方法注入的时候:

  • 可以通过下标
  • 可以通过参数名
  • 也可以不指定下标和参数名,可以类型自动推断。

Spring在装配方面做的比较健壮。

3. p命名空间注入

目的:简化配置。

使用p命名空间注入的前提条件包括两个:

  • 第一:在XML头部信息中添加p命名空间的配置信息:xmlns:p="http://www.springframework.org/schema/p"
  • 第二:p命名空间注入是基于setter方法的,所以需要对应的属性提供setter方法。
package com.powernode.spring6.beans;/*** @author 五度鱼* @version 1.0* @className Customer* @since 1.0**/
public class Customer {private String name;private int age;public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "Customer{" +"name='" + name + '\'' +", age=" + age +'}';}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="customerBean" class="com.powernode.spring6.beans.Customer" p:name="zhangsan" p:age="20"/></beans>
@Test
public void testP(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-p.xml");Customer customerBean = applicationContext.getBean("customerBean", Customer.class);System.out.println(customerBean);
}

执行结果:

4. c命名空间注入

c命名空间是简化构造方法注入的。

使用c命名空间的两个前提条件:

第一:需要在xml配置文件头部添加信息:xmlns:c=“http://www.springframework.org/schema/c”

第二:需要提供构造方法。

package com.powernode.spring6.beans;/*** @author 五度鱼* @version 1.0* @className MyTime* @since 1.0**/
public class MyTime {private int year;private int month;private int day;public MyTime(int year, int month, int day) {this.year = year;this.month = month;this.day = day;}@Overridepublic String toString() {return "MyTime{" +"year=" + year +", month=" + month +", day=" + day +'}';}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:c="http://www.springframework.org/schema/c"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--<bean id="myTimeBean" class="com.powernode.spring6.beans.MyTime" c:year="1970" c:month="1" c:day="1"/>--><bean id="myTimeBean" class="com.powernode.spring6.beans.MyTime" c:_0="2008" c:_1="8" c:_2="8"/></beans>
@Test
public void testC(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-c.xml");MyTime myTimeBean = applicationContext.getBean("myTimeBean", MyTime.class);System.out.println(myTimeBean);
}

执行结果:


最后求个关注,点赞,收藏,谢谢!

【Spring】Spring的IOC依赖注入的四种方式相关推荐

  1. Spring IOC (DI) 依赖注入的四种方式

    依赖注入的四种方式: set 注入 赋值,默认使用的是set() 方法,依赖注入底层是通过反射实现的 <bean id="student" class="cust. ...

  2. java中四种注入注解,Spring中依赖注入的四种方式

    在Spring容器中为一个bean配置依赖注入有三种方式: · 使用属性的setter方法注入  这是最常用的方式: · 使用构造器注入: · 使用Filed注入(用于注解方式). 使用属性的sett ...

  3. java调用外联服务用xml,Spring IOC 依赖注入的两种方式:XML和注解

    IoC,直观地讲,就是容器控制程序之间的关系,而非传统实现中,由程序代码直接操控.这也就是所谓"控制反转"的概念所在.控制权由应用代码中转到了外部容器,控制权的转移是所谓反转.Io ...

  4. spring依赖注入的四种方式

    平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程 ...

  5. Spring系列之依赖注入的三种方式

    目录 一.依赖注入方式 1.使用属性的setXXX方法注入 2.构造函数注入 (1)按类型匹配入参type (2)按索引匹配入参index (3)联合使用类型和索引匹配入参[type和index一起使 ...

  6. spring依赖注入的4种方式

    Spring 依赖注入的4种方式 一.Set注入 必须要有setter方法 public class UserDao {public void test(){System.out.println(&q ...

  7. Spring实现依赖注入的几种方式

    Spring实现依赖注入的几种方式 1.基于有参构造实现 <bean id="user" class="com.ccu.twj"><const ...

  8. spring依赖注入简介以及依赖注入的两种方式

    1.spring依赖注入简介 依赖注入:Set注入1.依赖:bean对象创建依赖于容器!2.注入:bean对象中的所有属性,由容器来注入! 2.依赖注入的两种方式   实体类: package com ...

  9. spring依赖注入的三种方式以及优缺点

    spring依赖注入的三种方式以及优缺点 一.依赖注入的三种方式 1.通过构造器注入.(spring4.3之后,推荐使用) 2.通过setter注入.(spring4.3之前,推荐使用) 3通过fil ...

最新文章

  1. TCP丢包检测技术详解
  2. python高性能服务器编写,Tornado的高性能服务器开发常用方法
  3. 数据预处理--样本选择、交叉验证
  4. QuickSort简解(分治思想) By ACReaper
  5. css-3秒(大概吧...)快速撸出YY游戏页面(三)
  6. c# Linq Where 抛出异常 导致 程序崩溃
  7. java 连接eureka_在同一应用程序中的配置服务器和eureka服务器:尝试连接到localhost:8761...
  8. Atitit。Time base gc 垃圾 资源 收集的原理与设计
  9. 【交换机在江湖】第十五章 VLAN隔离篇
  10. windows系统常用运行命令大全
  11. 高等数学笔记:两个重要极限
  12. 有没有什么软件可以把视频转文字?看看这些转换软件
  13. python内存泄漏_诊断和修复Python中的内存泄漏
  14. 混音软件哪个好用?这几个软件不容错过
  15. Appium报错Original error: Could not proxy command to the remote server. Original error: socket hang up
  16. 为什么应对危机,企业倒闭比裁员好,裁员比降薪好?
  17. excel php时间,excel时间函数
  18. Visual Studio 2017无法验证许可证状态、登陆报错the broswer based authentication dialog failed to complete-亲测可行
  19. 基于MFC的通讯录管理系统设计与实现
  20. 央视影音大屏版apk下载_央视影音大屏版

热门文章

  1. 超详细!旗舰SoC RK3588参数介绍-飞凌嵌入式
  2. YII2框架中 where limit offset 函数对分页的使用
  3. STK中的传感器、雷达、发射机、接收机、天线
  4. 收藏这份《Android车载系统应用指南》,助你轻松入门,斩获高薪
  5. SEM-X射线荧光固体制样方法,请收好!
  6. Verilog HDL的简单应用之74ls160功能的实现
  7. scheme的应用序
  8. 集电极开路是什么?集电极开路电路工作原理讲述
  9. python毕业设计 机器视觉驾驶人脸疲劳检测系统 - opencv
  10. 关于自动白平衡的算法问题