Bean的依赖注入方式与数据类型
本文最后更新于:1 年前
IoC (Inverse of Control)—— 控制反转。通过Spring对象工厂完成对象的创建。
DI (Dependency Injection)——依赖注入。在Spring完成对象创建的同时,依赖Spring容器完成对象属性的赋值。
依赖注入(Dependency Injection)是 Spring 框架核心 IOC 的具体实现。
案例引入
创建 UserService,UserService 内部在调用 UserDao的save() 方法
1
2
3
4
5
6
7
8public class UserServiceImpl implements UserService {
@Override
public void save() {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) app.getBean("userDao");
userDao.save();
}
}将 UserServiceImpl 的创建权交给 Spring
1
2<bean id="userDao" class="cc.gaojie.dao.impl.UserDaoImpl" ></bean>
<bean id="userService" class="cc.gaojie.service.impl.UserServiceImpl"></bean>从 Spring 容器中获得 UserService 进行操作
1
2
3
4
5
6
7
8
9public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) app.getBean("userService");
userService.save();
}
}
目前 UserService 实例和 UserDao 实例都存在与Spring容器中,当前的做法是在容器外部获得 UserService 实例和 UserDao 实例,然后在程序中进行结合。
因为 UserService 和 UserDao 都在 Spring 容器中,而最终程序直接使用的是 UserService,所以可以在 Spring 容器中,将 UserDao 设置到 UserService 内部。
依赖注入简介
依赖注入(Dependency Injection)是 Spring 框架核心 IOC 的具体实现。
在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。
控制反转与依赖注入
控制反转(IoC )
当我们需要通过Spring对象工厂创建某个类的对象时候,需要将这个交给Spring管理——通过bean标签配置。
1 |
|
依赖注入(DI)
即通过Spring容器给创建的对象属性赋值。
1 |
|
依赖注入方式与数据类型
怎么将UserDao注入到UserService内部呢?
Spring容器加载配置文件之后,通过反射
创建类的对象,并给属性赋值。Spring容器通过反射实现属性注入有三种方式:
set方法注入
在bean标签中通过配置property标签给属性属性赋值,实际上就是通过反射调用set方法完成属性的注入。
常规 set 方法注入
在 UserServiceImpl 中添加 setUserDao 方法
1
2
3
4
5
6
7
8
9
10
11
12
13public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}配置 Spring 容器调用 set 方法进行注入
1
2
3
4
5<bean id="userDao" class="cc.gaojie.dao.impl.UserDaoImpl" ></bean>
<bean id="userService" class="cc.gaojie.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>从 Spring 容器中获得 UserService 进行操作
1
2
3
4
5
6
7
8
9public class UserController {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) app.getBean("userService");
userService.save();
}
}
P 命名空间注入
P 命名空间注入本质也是 set 方法注入,但比起上述的 set 方法注入更加方便,主要体现在配置文件中。
首先,需要引入P命名空间:
1
xmlns:p="http://www.springframework.org/schema/p"
其次,需要修改注入方式:
1
2
3<bean id="userDao" class="cc.gaojie.dao.impl.UserDaoImpl"></bean>
<!--p命名空间注入-->
<bean id="userService" class="cc.gaojie.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean>
不同数据类型属性的注入方式
上面的操作,都是注入的引用 Bean,除了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入。
注入数据的三种数据类型:
- 普通数据类型
- 引用数据类型
- 集合数据类型
简单类型及字符串
直接通过 property 标签的 value 属性赋值。
1 |
|
日期类型
方式1:在property标签中通过ref引用Spring容器中的一个对象
1
2
3
4
5
6<bean id="date" class="java.util.Date"></bean>
<bean id="stu" class="cc.gaojie.ioc.bean.Student" >
<!-- 日期类型-->
<property name="enterenceTime" ref="date"/>
</bean>方式2:在property标签中添加子标签bean来指定对象
1
2
3
4
5
6<bean id="stu" class="cc.gaojie.ioc.bean.Student" >
<!-- 日期类型-->
<property name="enterenceTime">
<bean class="java.util.Date"/>
</property>
</bean>
自定义类对象属性
方式1:在property标签中通过ref直接引用
1
2
3
4
5
6
7
8
9<bean id="cla" class="cc.gaojie.ioc.bean.Clazz">
<property name="classId" value="2010"/>
<property name="className" value="Java2010"/>
</bean>
<bean id="stu" class="cc.gaojie.ioc.bean.Student">
<!-- 自定义对象类型-->
<property name="clazz" ref="cla"/>
</bean>方式2:在property标签中添加子标签bean来指定对象
1
2
3
4
5
6
7
8
9<bean id="stu" class="cc.gaojie.ioc.bean.Student">
<!-- 自定义对象类型-->
<property name="clazz">
<bean class="cc.gaojie.ioc.bean.Clazz">
<property name="classId" value="2010"/>
<property name="className" value="Java2010"/>
</bean>
</property>
</bean>
集合类型
List
List<String>
List中的元素是字符串或者简单类型的封装类,可直接赋值。1
2<!-- 方式一 -->
<property name="hobbies" value="旅游,电影"/>1
2
3
4
5
6
7
8<!-- 方式二 -->
<property name="hobbies" >
<list>
<value>旅游</value>
<value>电影</value>
<value>Java</value>
</list>
</property>List<Object>
List中的元素是对象类型1
2
3
4
5
6
7
8
9<!-- 方式一 -->
<property name="hobbies" >
<list>
<bean class="cc.gaojie.ioc.bean.Book"/>
<bean class="cc.gaojie.ioc.bean.Book"/>
<bean class="cc.gaojie.ioc.bean.Book"/>
<bean class="cc.gaojie.ioc.bean.Book"/>
</list>
</property>1
2
3
4
5
6
7
8
9<!-- 方式二 -->
<bean id="book" class="cc.gaojie.ioc.bean.Book"/>
<property name="hobbies" >
<list>
<ref bean="book"></ref> <!--引用容器中的bean-->
<ref bean="book"></ref>
</list>
</property>
Set
1 |
|
Map
1 |
|
Properties
1 |
|
构造方法注入
所谓构造方法注入,是指使用被Spring管理的类的构造器,来完成属性的赋值。
简单类型、字符串、对象
1 |
|
1 |
|
集合类型属性
1 |
|
1 |
|
案例演示
以 set 方法注入为例,演示普通数据类型和集合数据类型的注入。
普通数据类型的注入
1 |
|
1 |
|
1 |
|
集合数据类型的注入
1 |
|
1 |
|
1 |
|
1 |
|
构造器注入
创建有参构造方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl() {
}
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}配置 Spring 容器调用有参构造时进行注入
不配置默认调无参,但无参构造方法获取不到 UserDao 实例,userDao 为空无法注入给 UserService。
1
2
3
4
5<bean id="userDao" class="cc.gaojie.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="cc.gaojie.service.impl.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>从 Spring 容器中获得 UserService 进行操作
1
2
3
4
5
6
7
8public class UserDaoDemo {
public static void main(String[] args) {
//加载Spring核心文件
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) app.getBean("userService");
userService.save();
}
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!