Spring-Bean的依赖注入分析-01
###我们先通过一个例子弄明白为什么要使用依赖注入###
1.创建业务层UserService接口及UserServiceImpl实现类(接口代码省略)
public class UserServiceImpl implements UserService {
@Override
public void sava() {
ApplicationContext app=new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao1 = (UserDao) app.getBean("userDao");
userDao1.save();
}
}
2.创建DAO层的UserDao接口及UserDaoImpl实现类(接口代码省略)
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("save running...");
}
}
3.配置spring的applicationContext.xml配置文件
<?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="userDao" class="com.hao.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.hao.service.impl.UserServiceImpl"/>
</beans>
//告诉spring容器类的位置,使用bean将service类和dao类配置到spring配置文件中,
//id为唯一性标识,外部可以通过getBean("id");从spring容器中获取对象
4.Controller层进行测试
public class UserController {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService service = (UserService) context.getBean("userService");
service.sava();
}
}
//加载spring配置文件,创建spring容器
//通过getBean方法获取从spring容器中对象
分析:目前UserSerivce实例和UserDao实例都存在spring容器当中,当前的做法是外部从spring容器获得UserService实例和UserDao实例,然后在程序中完成调用
思考:我们在Controller层用的是service,不管Dao是怎么获取的,我们想那么能不能在spring容器内部就完成service调用Dao的操作呢?
(因为UserService和UserDao都在spring的容器中,而最终程序直接使用的是UserService,所以可以在spring容器中,将UserDao设置到UserService内部)
===================================================
然后实现以上问题就是使用依赖注入了
依赖注入:它是spring框架核心IOC的具体实现
在编写程序时,通过控制反转,把对象的创建交给了spring,但是代码中不可能出现没有依赖的情况。IOC解耦只是降低他们的依赖关系,但不会消除,例如:业务层仍会调用持久层的方法
那这种业务层和持久层的依赖关系,在使用spring之后,就让Spring来维护了。
简单的说:就是坐等框架把持久层对象传入业务层,而不用我们自己去获取
=========================================================================================================================================================
接下来就是dao注入给service了
1.构造方法
2.set方法
演示set方法注入
(1)创建UserDao接口以及UserDaoImpl实现类
public class UserDaoImpl implements UserDao {
@Override
public void save1() {
System.out.println("save running...");
}
}
(2)创建UserService接口以及UserServiceImpl实现类
注意:这里使用了在UserServiceImplt中添加了UserDao属性,因为使用set方法进行注入,所以实现属性的set方法
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void sava() {
userDao.save1();
}
}
(3)spring配置文件的实现
<?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="userDao" class="com.hao.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.hao.service.impl.UserServiceImpl">
//这里面的name属性值是set方法名去掉set三个字和U变小写,ref属性是引入dao中bean实例的id标识符,这里是第一个bean标签中的id
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
(4)Controller前端测试
public class UserController {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService service = (UserService) context.getBean("userService");
service.sava();
}
}
结果:save running . . .
这样就实现了set注入
进阶点:
接下来我们来思考一个问题,如果我把Controller前端代码改成如下
public class UserController {
public static void main(String[] args) {
// ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
// UserService service = (UserService) context.getBean("userService");
// service.sava();
UserService userService=new UserServiceImpl();
userService.sava();
}
}
我们不从容器中获取UserService对象了,自己new了一个UserService对象,然后调用方法,这样会出现什么情况呢
我们发现出现了空指针异常,然后定位到代码错误处
16行出现了userDao报了空,那么也就是第8行空,那这是什么原因呢?
原因是:我们的UserService对象不是从容器中获取的,而是自己new出来的,那么UserDao是在spring容器中注入给UserService的,你不从spring容器中获取UserService对象,那么就会出现UserDao为空的异常
下一篇博客我们讲通过p命名空间注入,简化操作
最新文章
- SQLite如何测试
- 获取ICommand的图片
- ANSI C 所有的转义字符
- selenium定位失败记录
- 【ZZ】MySql语句大全:创建、授权、查询、修改等
- swift - use backslash to add the value in the string
- Android之 compileSdkVersion, minSdkVersion, and targetSdkVersion
- scull_p_read()函数分析
- java中long类型的比较
- JSP之连接SQL Server
- ACM总结——2017区域赛网络赛总结
- C#6.0语言规范(一) 介绍
- communication
- [EXP]WordPress Core 5.0 - Remote Code Execution
- HDU 2015 偶数求和
- JavaScript中hoisting(悬置/置顶解析/预解析) 实例解释,全局对象,隐含的全局概念
- PHP下ajax跨子域的解决方案之document.domain+iframe
- [Virus Analysis]恶意软件分析(二)玩出花的批处理(中)
- Cannot enlarge string buffer containing XX bytes by XX more bytes
- Ofstream的endl不好用怎么回事?