Spring 支持 4 种依赖注入的方式
属性注入
构造器注入
工厂方法注入(静态工厂方法、实例工厂方法)
FactoryBean
属性注入
属性注入即通过 setter 方法注入Bean 的属性值或依赖的对象
属性注入使用 <property> 元素, 使用 name 属性指定 Bean 的属性名称,value 属性或 <value> 子节点指定属性值
属性注入是实际应用中最常用的注入方式
<!--配置一个 bean--> <bean id="department1" class="xyz.huning.spring4.di.Department"> <!--属性注入--> <property name="id"> <value>1</value> </property> <property name="name"> <value>Newton</value> </property> </bean>
构造器注入
通过构造方法注入Bean 的属性值或依赖的对象,它保证了 Bean 实例在实例化后就可以使用。
构造器注入在 <constructor-arg> 元素里声明属性, <constructor-arg> 中没有 name 属性
按索引匹配入参:
<!--配置一个 bean--> <!-- 若一个 bean 有多个构造器, 如何通过构造器来为 bean 的属性赋值 --> <!-- 可以根据 index 和 value 进行更加精确的定位.--> <bean id="employee2" class="xyz.huning.spring4.di.Employee"> <!--构造器注入--> <!-- 要求: 在 Bean 中必须有对应的构造器.--> <!--按索引匹配入参--> <constructor-arg value="2" index="0"></constructor-arg> <constructor-arg value="huning" index="1"></constructor-arg> <constructor-arg value="male" index="2"></constructor-arg> </bean>
按类型匹配入参:
<!--配置一个 bean--> <bean id="employee3" class="xyz.huning.spring4.di.Employee"> <!--构造器注入--> <!--按类型匹配入参--> <constructor-arg value="3" type="int"></constructor-arg> <constructor-arg value="yingzi" type="java.lang.String"></constructor-arg> <constructor-arg ref="department1" type="xyz.huning.spring4.di.Department"></constructor-arg> </bean>
字面量
字面值:可用字符串表示的值,可以通过 <value> 元素标签或 value 属性进行注入。
基本数据类型及其封装类、String 等类型都可以采取字面值注入的方式
若字面值中包含特殊字符,可以使用 <![CDATA[]]> 把字面值包裹起来。
<!--配置一个 bean--> <bean id="department2" class="xyz.huning.spring4.di.Department"> <property name="id" value="2"></property> <!--若字面值中包含特殊字符, 则可以使用 DCDATA 来进行赋值.--> <property name="name"> <value><![CDATA[<Newton>]]></value> </property> </bean>
引用其它 Bean
组成应用程序的 Bean 经常需要相互协作以完成应用程序的功能. 要使 Bean 能够相互访问, 就必须在 Bean 配置文件中指定对 Bean 的引用
在 Bean 的配置文件中, 可以通过 <ref> 元素或 ref 属性为 Bean 的属性或构造器参数指定对 Bean 的引用.
也可以在属性或构造器里包含 Bean 的声明, 这样的 Bean 称为内部 Bean
<!--配置一个 bean--> <bean id="employee1" class="xyz.huning.spring4.di.Employee"> <!--属性注入--> <!-- 通过属性注入: 通过 set方法注入属性值 --> <property name="id" value="1"></property> <!--通过 ref属性值指定当前属性指向哪一个bean--> <property name="department" ref="department1"></property> </bean>
内部 Bean
当 Bean 实例仅仅给一个特定的属性使用时, 可以将其声明为内部 Bean. 内部 Bean 声明直接包含在 <property> 或 <constructor-arg> 元素里, 不需要设置任何 id 或 name 属性
内部 Bean 不能使用在任何其他地方
<!--配置一个 bean--> <bean id="employee4" class="xyz.huning.spring4.di.Employee"> <property name="id" value="4"></property> <property name="department"> <!-- 内部 bean, 类似于匿名内部类对象. 不能被外部的 bean 来引用, 也没有必要设置 id 属性 --> <bean class="xyz.huning.spring4.di.Department"> <property name="id" value="3"></property> <property name="name" value="Gaussian"></property> </bean> </property> </bean>
注入参数详解:null 值和级联属性
可以使用专用的 <null/> 元素标签为 Bean 的字符串或其它对象类型的属性注入 null 值
和 Struts、Hiberante 等框架一样,Spring 支持级联属性的配置。
<!--配置一个 bean--> <bean id="employee5" class="xyz.huning.spring4.di.Employee"> <property name="id" value="5"></property> <!--使用专用的 <null/> 元素标签为 Bean 的字符串或其它对象类型的属性注入 null 值--> <property name="department"><null/></property> </bean>
Java代码
package xyz.huning.spring4.di; public class Department { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Department [id=" + id + ", name=" + name + "]"; } }
package xyz.huning.spring4.di; public class Employee { private int id; private String name; private String gender; private Department department; public Employee() { } public Employee(int id, String name, String gender) { this.id = id; this.name = name; this.gender = gender; } public Employee(int id, String name, Department department) { this.id = id; this.name = name; this.department = department; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } @Override public String toString() { return "Employee [id=" + id + ", name=" + name + ", gender=" + gender + ", department=" + department + "]"; } }
package xyz.huning.spring4.di; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("di.xml"); Employee employee1 = context.getBean("employee1", Employee.class); System.out.println(employee1); Employee employee2 = context.getBean("employee2", Employee.class); System.out.println(employee2); Employee employee3 = context.getBean("employee3", Employee.class); System.out.println(employee3); Employee employee4 = context.getBean("employee4", Employee.class); System.out.println(employee4); Department department2 = context.getBean("department2", Department.class); System.out.println(department2); Employee employee5 = context.getBean("employee5", Employee.class); System.out.println(employee5); Employee employee6 = context.getBean("employee6", Employee.class); System.out.println(employee6); } }
静态工厂方法&实例工厂方法
添加类模型:
package xyz.huning.spring4.factorymethod; public class Car { private int id; private String brand; private double price; public Car() { } public Car(int id,String brand,double price) { this.id = id; this.brand = brand; this.price = price; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "Car [id=" + id + ", brand=" + brand + ", price=" + price + "]"; } }
package xyz.huning.spring4.factorymethod; import java.util.HashMap; import java.util.Map; /** * * 静态工厂方法:直接调用某个类的静态方法就可以返回bean实例 */ public class StaticCarFactory { private static Map<Integer,Car> cache = new HashMap<Integer,Car>(); static{ Car car1 = new Car(1,"QQ",50000); Car car2 = new Car(2,"BMW",200000); cache.put(car1.getId(), car1); cache.put(car2.getId(), car2); } //静态工厂方法 public static Car getCar(int id) { return cache.get(id); } }
package xyz.huning.spring4.factorymethod; import java.util.HashMap; import java.util.Map; /** * 实例工厂方法:需要先创建共产本身,在调用工厂的实例方法来返回bean的实例 * * @author Administrator * */ public class InstanceCarFactory { private Map<Integer,Car> cache = new HashMap<Integer,Car>(); public InstanceCarFactory() { Car car1 = new Car(1,"QQ",50000); Car car2 = new Car(2,"BMW",200000); this.cache.put(car1.getId(), car1); this.cache.put(car2.getId(), car2); } public Car getCar(int id) { return this.cache.get(id); } }
添加配置:
<?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-> <!--通过静态工厂方法来配置bean.注意不是配置静态工厂方法实例.而是配置bean实例--> <!-- class 属性:指向静态工厂方法的全类名 factory-method:指向静态工厂方法的名字 constructor-arg:如果工厂方法需要传入参数,则使用constructor-arg来配置参数 --> <bean id="car1" class="xyz.huning.spring4.factorymethod.StaticCarFactory" factory-method="getCar"> <constructor-arg name="id" value="1"></constructor-arg> </bean> <!--实例工厂方法配置bean-> <!--配置工厂的实例--> <bean id="instanceCarFactory" class="xyz.huning.spring4.factorymethod.InstanceCarFactory"></bean> <!--通过实例工厂方法来配置bean--> <!-- factory-bean: 属性:指向工厂的实例 factory-method:指向实例工厂方法的名字 constructor-arg:如果工厂方法需要传入参数,则使用constructor-arg来配置参数 --> <bean id="car2" factory-bean="instanceCarFactory" factory-method="getCar"> <constructor-arg name="id" value="2"></constructor-arg> </bean> </beans>
添加测试类:
package xyz.huning.spring4.factorymethod; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("factorymethod.xml"); Car car1 = context.getBean("car1", Car.class); System.out.println(car1); Car car2 = context.getBean("car2", Car.class); System.out.println(car2); ((ClassPathXmlApplicationContext)context).close(); } }
FactoryBean
添加类模型:
package xyz.huning.spring4.factorybean; public class Airplane { private int id; private String type; public Airplane() {} public Airplane(int id,String type) { this.id = id; this.type = type; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getType() { return type; } public void setType(String type) { this.type = type; } @Override public String toString() { return "Airplane [id=" + id + ", type=" + type + "]"; } }
package xyz.huning.spring4.factorybean; import org.springframework.beans.factory.FactoryBean; /** * * 自定义的FactoryBean需要实现FactoryBean的接口 * * @author Administrator * */ public class FactoryBeanImpl implements FactoryBean<Airplane> { private int id; private String type; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getType() { return type; } public void setType(String type) { this.type = type; } @Override public Airplane getObject() throws Exception { return new Airplane(id,type); } @Override public Class<?> getObjectType() { return Airplane.class; } @Override public boolean isSingleton() { return false; } }
添加配置:
<?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"> <!--通过FactoryBean来配置bean的实例--> <!-- class : 指向FactoryBean的全类名 property: 配置FactoryBean的属性 实际返回的对象是FactoryBean的getObject方法返回的实例 --> <bean id="airplane1" class="xyz.huning.spring4.factorybean.FactoryBeanImpl"> <property name="id" value="101"></property> <property name="type" value="military"></property> </bean> </beans>
添加测试类:
package xyz.huning.spring4.factorybean; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("factorybean.xml"); Airplane airplane1 = context.getBean("airplane1", Airplane.class); System.out.println(airplane1); ((ClassPathXmlApplicationContext)context).close(); } }
相关推荐
Spring的依赖注入提供了XML、注解和Java配置等多种方式,满足不同场景的需求。自动配置是Spring Boot的一大特色,极大地简化了微服务的开发。理解并熟练掌握这些方式,对于提升Spring应用的开发效率和质量至关重要。...
Spring依赖注入是Spring框架的核心特性之一,它极大地简化了Java应用程序的开发,使得对象之间的依赖关系得以解耦,提高了代码的可测试性和可维护性。本文将深入探讨Spring依赖注入的底层实现机制。 首先,我们要...
通过阅读和理解这些源码,你可以更深入地了解Spring依赖注入的工作原理及其在项目中的具体使用。 在进行依赖注入时,Spring使用BeanFactory或ApplicationContext作为容器,负责创建、管理和装配Bean。容器读取配置...
本项目以"Spring_依赖注入_面向接口编程_不同加载方式"为主题,旨在帮助初学者理解Spring的核心特性——依赖注入(Dependency Injection,简称DI),以及如何通过面向接口编程来提高代码的可维护性和可扩展性。...
Spring依赖注入是Spring框架的核心特性之一,它使得对象之间的依赖关系得以解耦,增强了代码的可测试性和可维护性。依赖注入(Dependency Injection,简称DI)的理念是,一个对象不应该负责寻找并创建它所依赖的对象...
Spring依赖注入(Dependency Injection,简称DI)是Java应用开发中常用的设计模式,它极大地提高了代码的可测试性和可维护性。在Spring框架中,依赖注入是核心特性之一,通过控制反转(Inversion of Control,IoC)...
本篇文章将深入探讨Spring4的依赖注入机制,包括其概念、实现方式以及在实际开发中的应用。 一、依赖注入的概念 依赖注入是面向对象设计原则之一,它将对象之间的依赖关系反转,由外部容器负责管理对象及其依赖。...
1. **XML配置**:传统的Spring配置方式,通过`<bean>`标签定义对象及其依赖。 2. **Java注解配置**:使用如`@Component`、`@Service`、`@Repository`和`@Controller`等注解来标记组件,以及`@Autowired`、`@...
本篇将详细介绍Spring依赖包和配置文件的相关知识。 一、Spring依赖包 1. **Spring Core**:这是Spring框架的核心部分,提供了IoC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入)服务。...
在`chapter8`这个文件夹中,可能包含了关于Spring依赖注入的深入讲解,包括如何配置和使用,以及在实际项目中的应用示例。学习这部分内容可以帮助你理解如何利用Spring的DI特性来构建更优雅、更易于维护的Java应用。...
依赖注入(DI)是Spring框架的核心特性之一,它允许我们把对象的依赖关系从代码中解耦出来,转而由Spring容器来管理。在传统的编程模式中,对象通常自行创建和管理它们所依赖的对象,但在Spring中,这些依赖是由外部...
在IT行业中,Spring框架是Java开发中的一个基石,尤其在控制反转(IoC)和依赖注入(DI)方面。依赖注入是一种设计模式,它允许我们解耦组件,提高代码的可测试性和可维护性。Spring框架通过IoC容器来实现DI,让我们...
在Spring.NET中,依赖注入可以通过XML配置或代码注解两种方式进行。在提供的例子中,我们很可能会看到XML配置文件的使用,这是Spring.NET早期版本中常用的方法。 1. **XML配置**:Spring.NET的配置文件通常命名为`...
**Spring.NET依赖注入(DI)和控制反转(IOC)概念** Spring.NET是一个针对.NET平台的开源框架,它引入了依赖注入(Dependency Injection,简称DI)和控制反转(Inversion of Control,简称IOC)的设计模式,使得...
在Spring框架中,依赖注入(Dependency Injection,简称DI)是一种重要的设计模式,它极大地提高了代码的可测试性和可维护性。模拟Spring的依赖注入,旨在理解其核心机制,让我们一起深入探讨这一主题。 首先,我们...
2. **依赖注入**:Spring通过XML配置或者注解方式实现依赖注入。例如,可以在Action类中声明SessionFactory的setter方法,Spring会自动将SessionFactory实例注入到Action中。 ```java public class MyAction { ...
依赖注入是Spring框架的核心特性之一,它帮助减少对象之间的耦合。在传统的Java代码中,对象常常通过构造函数、setter方法或全局变量来获取依赖。而依赖注入则是由外部容器(如Spring IoC容器)负责创建对象并管理...
下面我们将深入探讨Spring依赖注入的概念、工作原理以及如何在实践中应用。 1. **依赖注入概念**: - 依赖:一个类对另一个类的使用称为依赖。 - 注入:将依赖的对象传递给需要它的类,而不是由类自己去创建或...
在Spring中,依赖注入通过容器来管理对象及其相互之间的依赖关系。 首先,让我们深入理解依赖注入的概念。依赖注入是指将一个对象所需的依赖对象传递给它,而不是由该对象自己创建或查找。这样,对象只需要关注自己...
本篇文章将深入探讨Spring框架中的依赖注入及其相关知识。 首先,我们要理解什么是依赖注入。依赖注入是指一个对象不再自行创建或查找其依赖的对象,而是由外部容器(在Spring中就是ApplicationContext)在运行时...