###我们先通过一个例子弄明白为什么要使用依赖注入###

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命名空间注入,简化操作

最新文章

  1. SQLite如何测试
  2. 获取ICommand的图片
  3. ANSI C 所有的转义字符
  4. selenium定位失败记录
  5. 【ZZ】MySql语句大全:创建、授权、查询、修改等
  6. swift - use backslash to add the value in the string
  7. Android之 compileSdkVersion, minSdkVersion, and targetSdkVersion
  8. scull_p_read()函数分析
  9. java中long类型的比较
  10. JSP之连接SQL Server
  11. ACM总结——2017区域赛网络赛总结
  12. C#6.0语言规范(一) 介绍
  13. communication
  14. [EXP]WordPress Core 5.0 - Remote Code Execution
  15. HDU 2015 偶数求和
  16. JavaScript中hoisting(悬置/置顶解析/预解析) 实例解释,全局对象,隐含的全局概念
  17. PHP下ajax跨子域的解决方案之document.domain+iframe
  18. [Virus Analysis]恶意软件分析(二)玩出花的批处理(中)
  19. Cannot enlarge string buffer containing XX bytes by XX more bytes
  20. Ofstream的endl不好用怎么回事?

热门文章

  1. Windows 下 MySQL 简单定时自动备份、删除过期备份
  2. SQLMAP-Tamper之较为通用的双写绕过
  3. vant中tab标签切换时会改变内容滚动高度
  4. java反射获取类的成员函数,成员变量,构造函数
  5. Kubernetes 使用kubeadm创建集群
  6. springboot 踩坑之路之 Configuration Annotation Proessor not found in classpath
  7. Nebula Graph 在网易游戏业务中的实践
  8. python3 爬虫3--异常处理
  9. Pytorch自动混合精度(AMP)介绍与使用
  10. 监听watch?