Spring依赖注入的方式自己整理的

7 篇文章 0 订阅

Spring依赖注入的方式

Spring依赖注入(DI)有三种方式:

- Setter方法注入
- 构造方法注入
- 基于注解注入
- 静态工厂的方法注入
- 实例工厂的方法注入

1、setter方法注入

最简单的注入方式。

值类型用value注入,引用类型用ref注入。

假设有一个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” class="">,这样其实是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>

解决构造方法参数的不确定性,可能会遇到构造方法传入的两个参数都是同类型的,为了赋值能够对应,有两种处理方式:

1. 设置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> 

2. 设置参数类型:

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

3、基于注解的注入

首先了解一下bean的autowire属性,它有三个属性值:constructor、byName、byType。

 - constructor:通过构造方法进行自动注入,spring会会匹配与构造方法参数类型一致的bean进行注入,如果有一个多参数
 的构造方法,一个只有一个参数的构造方法,在容器中查找到多个匹配多参数构造方法的bean,那么spring会优先将bean注入
 到多参数的构造方法中。
 - byName:被注入bean的id名必须与set方法后半截匹配,并且id名称的第一个单词首字母必须小写。
 - byType:查找所有的set方法,将符合参数类型的bean注入。

主要有四种注解可以注册bean,每种注解可以任意使用,只是语义上有差异:

@Component:可以用于注册所有bean。

@Repository:主要用于注册dao层的bean。

@Controller:主要用于注册控制层的bean。

@Service:主要用于注册服务层的bean。

描述依赖关系主要有两种:

@Resource:java的注解,默认以byName的方式去匹配与属性名相同的bean的id,如果没有找到就会以byType的方式查找,如果byType查找到多个的话,使用@Qualifier注解(spring注解)指定某个具体名称的bean。

@Resource
@Qualifier("userDaoMyBatis")
private IUserDao userDao;

public UserService(){

@Autowired:spring注解,默认是以byType的方式去匹配与属性名相同的bean的id,如果没有找到,就通过byName的方式去查找。

@Autowired
@Qualifier("userDaoJdbc")
private IUserDao userDao;

4、p名称空间注入(函数注入)

set注入是spring特有,为了简化< property >写法

  1. applicationContext.xml中< beans >标签头部导入p命名空间
xmlns:p="http://www.springframework.org/schema/p"
  1. 书写格式:
    值类型注入——p:属性名=“值”
    引用类型——p:属性名-ref=“引用的< bean >name属性”
    把Run类中的name属性值设置为haha,age属性设置为20,引用属性hello引用
<bean name="run2" class="cn.itcats.thread.Run" p:name="haha" p:age="20" p:hello-ref="hello"></bean>

5、spel注入(spring Expression Language spring表达式语言)


<bean name="runSpel" class="cn.itcats.thread.Run">
    <!-- 取bean标签中name为"user"中property为"name"中的value值 --!>
    <property name="name" value="#{user.name}"></property>
</bean>

SpEL特性:
(1)、使用Bean的ID来引用Bean;
(2)、调用方法和访问对象的属性;
(3)、对值进行算术、关系和逻辑运算;
(4)、正则表达式匹配;
(5)、集合操作

6、静态工厂的方法注入

通过调用静态工厂的方法来获取自己需要的对象,为了让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对象。

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> 
</bean> 
<!--(3)此处获取对象的方式是从工厂类中获取静态方法--> 
<bean name="staticFactoryDao" class="com.bless.springdemo.factory.DaoFactory" factory-method="getStaticFactoryDaoImpl"></bean>

7、实例工厂的方法注入

获取对象实例的方法不是静态的,所以需要首先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>

复杂类型注入

1、array数组的注入

在这里插入图片描述

2、list集合的注入

在这里插入图片描述

3、map集合的注入

在这里插入图片描述

4、properties的注入

在这里插入图片描述

总结

在实际的使用中setter注入构造函数注入使用的最多。

通过spring创建的对象默认是单例的。想创建多实例对象可以在< bean >标签中添加一个属性scope=prototype

<bean name="..." class="..." scope="prototype">
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值