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

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

posted on 2020-11-12 20:30  凸凸大军的一员  阅读(81)  评论(0编辑  收藏  举报