Spring 依赖注入方式详解

阅读目录

平常的Java开发中,程序员在某个类中需要依赖其它类的方法。

通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理。

Spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过Spring容器帮我们new指定实例并且将实例注入到需要该对象的类中。

依赖注入的另一种说法是"控制反转"。通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员。

而控制反转是指new实例工作不由我们程序员来做而是交给Spring容器来做。

Spring有多种依赖注入的形式,本篇文章仅介绍Spring通过xml进行IOC配置的方式。

回到顶部

1.Set注入

这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringDao的set方法(这是ioc的注入入口):

package com.bless.springdemo.action;
public class SpringAction {
//注入对象springDao
private SpringDao springDao;
//一定要写被注入对象的set方法
public void setSpringDao(SpringDao springDao) {
this.springDao = springDao;
} 

public void ok(){
springDao.ok();
}
}

随后编写spring的xml文件,<bean>中的name属性是class属性的一个别名,class属性指类的全名,因为在SpringAction中有一个公共属性Springdao,所以要在<bean>标签中创建一个<property>标签指定SpringDao。<property>标签中的name就是SpringAction类中的SpringDao属性名,ref指下面<bean name="springDao"...>,这样其实是spring将SpringDaoImpl对象实例化并且调用SpringAction的setSpringDao方法将SpringDao注入:

<!--配置bean,配置后该类由spring管理-->
<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
<!--(1)依赖注入,配置当前类中相应的属性-->
<property name="springDao" ref="springDao"></property>
</bean>
<bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean> 

回到顶部

2.构造器注入

这种方式的注入是指带有参数的构造函数注入,看下面的例子,我创建了两个成员变量SpringDao和User,但是并未设置对象的set方法,所以就不能支持第一种注入方式,这里的注入方式是在SpringAction的构造函数中注入,也就是说在创建SpringAction对象时要将SpringDao和User两个参数值传进来:

public class SpringAction {
//注入对象springDao
private SpringDao springDao;
private User user; 

public SpringAction(SpringDao springDao,User user){
this.springDao = springDao;
this.user = user;
System.out.println("构造方法调用springDao和user");
} 

public void save(){
user.setName("卡卡");
springDao.save(user);
}
} 

在XML文件中同样不用<property>的形式,而是使用<constructor-arg>标签,ref属性同样指向其它<bean>标签的name属性:

<!--配置bean,配置后该类由spring管理-->
<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
<!--(2)创建构造器注入,如果主类有带参的构造方法则需添加此配置-->
<constructor-arg ref="springDao"></constructor-arg>
<constructor-arg ref="user"></constructor-arg>
</bean>
<bean name="springDao" class="com.bless.springdemo.dao.impl.SpringDaoImpl"></bean>
<bean name="user" class="com.bless.springdemo.vo.User"></bean> 

解决构造方法参数的不确定性,你可能会遇到构造方法传入的两参数都是同类型的,为了分清哪个该赋对应值,则需要进行一些小处理:
下面是设置index,就是参数位置:

<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
<constructor-arg index="0" ref="springDao"></constructor-arg>
<constructor-arg index="1" ref="user"></constructor-arg>
</bean> 

另一种是设置参数类型:

<constructor-arg type="java.lang.String" ref=""/>

回到顶部

3.静态工厂的方法注入

静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,为了让spring管理所有对象,我们不能直接通过"工程类.静态方法()"来获取对象,而是依然通过spring注入的形式获取:

package com.bless.springdemo.factory; 

import com.bless.springdemo.dao.FactoryDao;
import com.bless.springdemo.dao.impl.FactoryDaoImpl;
import com.bless.springdemo.dao.impl.StaticFacotryDaoImpl; 

public class DaoFactory {
//静态工厂
public static final FactoryDao getStaticFactoryDaoImpl(){
return new StaticFacotryDaoImpl();
}
}

同样看关键类,这里我需要注入一个FactoryDao对象,这里看起来跟第一种注入一模一样,但是看随后的xml会发现有很大差别:

public class SpringAction {
//注入对象
private FactoryDao staticFactoryDao; 

public void staticFactoryOk(){
staticFactoryDao.saveFactory();
}
//注入对象的set方法
public void setStaticFactoryDao(FactoryDao staticFactoryDao) {
this.staticFactoryDao = staticFactoryDao;
}
} 

Spring的IOC配置文件,注意看<bean name="staticFactoryDao">指向的class并不是FactoryDao的实现类,而是指向静态工厂DaoFactory,并且配置 factory-method="getStaticFactoryDaoImpl"指定调用哪个工厂方法:

<!--配置bean,配置后该类由spring管理-->
<bean name="springAction" class="com.bless.springdemo.action.SpringAction" >
<!--(3)使用静态工厂的方法注入对象,对应下面的配置文件(3)-->
<property name="staticFactoryDao" ref="staticFactoryDao"></property>
</property>
</bean>
<!--(3)此处获取对象的方式是从工厂类中获取静态方法-->
<bean name="staticFactoryDao" class="com.bless.springdemo.factory.DaoFactory" factory-method="getStaticFactoryDaoImpl"></bean> 

回到顶部

4.实例工厂的方法注入

实例工厂的意思是获取对象实例的方法不是静态的,所以你需要首先new工厂类,再调用普通的实例方法:

public class DaoFactory {
//实例工厂
public FactoryDao getFactoryDaoImpl(){
return new FactoryDaoImpl();
}
}

那么下面这个类没什么说的,跟前面也很相似,但是我们需要通过实例工厂类创建FactoryDao对象:

public class SpringAction {
//注入对象
private FactoryDao factoryDao; 

public void factoryOk(){
factoryDao.saveFactory();
} 

public void setFactoryDao(FactoryDao factoryDao) {
this.factoryDao = factoryDao;
}
} 

最后看spring配置文件:

<!--配置bean,配置后该类由spring管理-->
<bean name="springAction" class="com.bless.springdemo.action.SpringAction">
<!--(4)使用实例工厂的方法注入对象,对应下面的配置文件(4)-->
<property name="factoryDao" ref="factoryDao"></property>
</bean> 

<!--(4)此处获取对象的方式是从工厂类中获取实例方法-->
<bean name="daoFactory" class="com.bless.springdemo.factory.DaoFactory"></bean>
<bean name="factoryDao" factory-bean="daoFactory" factory-method="getFactoryDaoImpl"></bean> 

5.总结

Spring IOC注入方式用得最多的是(1)(2)种,多写多练就会非常熟练。

另外注意:通过Spring创建的对象默认是单例的,如果需要创建多实例对象可以在<bean>标签后面添加一个属性:

<bean name="..." class="..." scope="prototype">
时间: 2024-10-13 03:07:32

Spring 依赖注入方式详解的相关文章

Spring事务Transaction配置的五种注入方式详解

Spring事务Transaction配置的五种注入方式详解 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. ??? 总结如下: ??? Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. ???DataSou

Unity依赖注入使用详解

Unity依赖注入使用详解 写在前面 构造器注入 Dependency属性注入 InjectionMethod方法注入 非泛型注入 标识键 ContainerControlledLifetimeManager单例 Unity注册配置问题 Unity的app.config节点配置 后记 关于 控制反转 (Inversion of Control)和 依赖注入 (Dependency Injection)大家网上可以找下相关概念,在 <小菜学习设计模式(五)—控制反转(Ioc)> 这篇文章中本人也

AngularJS开发指南10:AngularJS依赖注入的详解

依赖注入是一种软件设计模式,用来处理代码的依赖关系. 一般来说有三种方法让函数获得它需要的依赖: 它的依赖是能被创建的,一般用new操作符就行. 能够通过全局变量查找依赖. 依赖能在需要时被导入. 前两种方式都不是很好,因为它们需要对依赖硬编码,使得修改依赖的时候变得困难.特别是在测试的时候不好办,因为对某个部分进行孤立的测试常常需要模拟它的依赖. 第三种方式是最好的,因为它不必在组件中去主动寻找和获取依赖,而是由外界将依赖传入. 举个例子: function SomeClass(greeter

Spring依赖注入方式

1.创建一个User类 public class User { private String name; private int age; private Student student; private List<Student> list; private Map<String, String> map; //生成set和get } 2.依赖注入的数据类型是基本数据类型和字符串 2.1  通过set方法完成依赖注入 <bean id="user" cl

Spring IOC源码详解之容器依赖注入

Spring IOC源码详解之容器依赖注入 上一篇博客中介绍了IOC容器的初始化,通过源码分析大致了解了IOC容器初始化的一些知识,先简单回顾下上篇的内容 载入bean定义文件的过程,这个过程是通过BeanDefinitionReader来完成的,其中通过 loadBeanDefinition()来对定义文件进行解析和根据Spring定义的bean规则进行处理 - 事实上和Spring定义的bean规则相关的处理是在BeanDefinitionParserDelegate中完成的,完成这个处理需

spring中依赖注入方式总结

Spring中依赖注入的四种方式 在Spring容器中为一个bean配置依赖注入有三种方式: · 使用属性的setter方法注入  这是最常用的方式: · 使用构造器注入: · 使用Filed注入(用于注解方式). 使用属性的setter方法注入 首先要配置被注入的bean,在该bean对应的类中,应该有要注入的对象属性或者基本数据类型的属性.例如:为UserBiz类注入UserDAO,同时为UserBiz注入基本数据类型String,那么这时,就要为UserDAO对象和String类型设置se

spring中Bean的注入参数详解

字面值    一般指可用字符串表示的值,这些值可以通过<value>元素标签进行注入.在默认情况下,基本数据类型及其封装类.String等类型都可以采取字面值注入的方式,Spring容器在内部为字面值提供了编辑器,它可以将以字符串表示的字面值转换为内部变量的相应类型.    配置信息:    <bean id="car" class="com.luxl.domain.Car">        <property name="m

spring四种依赖注入方式

平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中.依赖注入的另一种说法是"控制反转",通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做. spring有多种

spring 四种依赖注入方式以及注解注入方式

平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化, 而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中.依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员, 而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做. spring有多种依赖注