Spring框架IOC学习

1.我们一开始最原始写代码,如果要在一个类中调用另一个类,必须先实例化被调用的对象(new对象)才能使用,写个例子。

1)dao层

接口:

public interface UserDao {
    void getUser();
}

实现类:

public class UserDaoImpl implements UserDao {

    public void getUser() {
        System.out.println("这是一个数据");
    }
}

2)service层

接口:

public interface UserService {
    void getUser();
}

实现类:

public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoImpl();
    public void getUser() {
        userDao.getUser();
    }
}

3)测试类

public class MyTest {
    public static void main(String[] args) {

        UserService userService = new UserServiceImpl();
        userService.getUser();
    }
}

这时如果如果dao层有改动,多了一个实现类:

public class UserDaoMysqlImpl implements UserDao{
    public void getUser() {
        System.out.println("Mysql");
    }
}

现在我们要用这个实现类,那么我们就必须修改service中实例化的对象也就是将:

private UserDao userDao = new UserDaoImpl();
改为
private UserDao userDao = new UserDaoMysqlImpl();

这显然违反我们java开发的开闭原则,开闭原则,对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的。

那么如何修改我们的程序达到不用修改service层就能实现以上的效果呢?我们可以使用set注入,修改代码如下:

public class UserServiceImpl implements UserService {
   
    private UserDao userDao;

    //利用set进行动态实现值的注入!
    public void setUserDao(UserDao userDao){
        this.userDao = userDao;
    }

    public void getUser() {
        userDao.getUser();
    }
}

我们在使用时可以直接通过set来注入:

public class MyTest2 {
    public static void main(String[] args) {

        UserService userService = new UserServiceImpl();
        //((UserServiceImpl) userService).setUserDao(new UserDaoImpl());
        ((UserServiceImpl) userService).setUserDao(new UserDaoOracleImpl());
        userService.getUser();
    }
}

这就是一个最原始的ioc的雏形,它使得之前程序主导创建对象的情况变成了程序被动注入,实现了控制反转

我们先用配置xml的方式来实现Spring bean对象的管理:

在resources文件夹中创建applicationContext.xml(名字可以随便取,但是Spirng官方文档中叫这个名字),并添加bean对象。

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
    bean就是spring为我们实例化的对象
    原来是 类型 变量名 = new 类型();
    bean就相当于这个过程
    bean标签里面的参数id就是变量名
    class指向全路径,你new的对象路径。
    -->
    <bean id="mysqlImpl" class="com.kuang.dao.UserDaoMysqlImpl"></bean>

<bean id="UserServiceImpl" class="com.kuang.service.UserServiceImpl"> <!-- ref:引用Spring容器中已经创建好的对象 value:具体的值,基本数据类型 --> <property name="userDao" ref="mysqlImpl"></property> </bean> </beans>

Spring官方为我们提供了ClassPathXmlApplicationContext类来获取容器:

public class MyTest {
    public static void main(String[] args) {
//获取ApplicationContext:拿到Spring的容器
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    //容器在手,天下我有,需要什么,就直接get什么
    UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("UserServiceImpl");
    userServiceImpl.getUser();
    }
}

一句话总结IOC本质:对象由Spring 来创建 , 管理 , 装配 。

posted @ 2020-03-06 23:51  yamiya  阅读(124)  评论(0编辑  收藏  举报