程序员社区

【Spring学习及总结03】何为IOC(控制反转)??

文章目录

    • 1.Spring的两个核心分类
    • 2.何为IOC(控制反转)?
    • 3.为什么需要IOC??
          • 第一步:先写Dao层的接口和实现类
          • 第二步:写Service层(应用层)
          • 第三步:写一个测试类,测试一下
          • 出现了问题:程序的耦合性太强
            • 1.使用setter方法改进
            • 2.使用构建函数改进

1.Spring的两个核心分类

需要学习IOC容器,因为以后可以用其来整合MyBatis,Hebernate,Stuts2等框架
需要学习AOP(面向切面编程)因为可以用于声明式事务
在这里插入图片描述

2.何为IOC(控制反转)?

控制:资源的获取
1.主动式:需要什么资源自给创建即可

BookServlet{
	BookService service = new BookService();
	AirPlan airPlan = new AirPlan();
	.....
}

总之,所谓的主动式就是:你需要什么对象你就自给去创建什么对象,但是这种方式会出现一定的问题,一会儿我们来看一个例子说明他的问题所在。

2.被动式:资源的获取不再是自己创建,而是交给一个容器来创建和设置

BookServlet{
	BookService service ;
	public void test1(){
		service.checkout();
	}
}

3.容器:管理所有的组件(有功能的类)
假设BookServlet和BookService都受容器管理,哪些容器就可以自动的探查出哪些组件需要另一些组件,容器就会帮我们创建对象,然后把对象赋值过去;
即主动的获取资源变为被动的接受;

4.DI(依赖注入)
容器能够知道哪个类运行的时候,需要另一个类;容器通过反射机制将容器中准备好的BookService对象注入给BookServlet中

3.为什么需要IOC??

下面通过一个例子来看一下传统的自己new对象的方式到底存在什么样的问题??

第一步:先写Dao层的接口和实现类

首先,我们先在Dao层中写一个接口,这个接口有三个实现类
在这里插入图片描述
UserDao接口:

public interface UserDao {
    void getUser();
}

UserDaoSqlServerImpl实现类:

public class UserDaoMySqlImpl implements UserDao {
    public void getUser() {
        System.out.println("MySql数据库");
    }
}

UserDaoMysqlImpl实现类:

public class UserDaoMySqlImpl implements UserDao {
    public void getUser() {
        System.out.println("MySql数据库");
    }
}

UserDaoOracleImpl实现类:

public class UserDaoOracleImpl implements UserDao {
    public void getUser() {
        System.out.println("Oracle数据库");
    }
}
第二步:写Service层(应用层)

在应用层中,我们去调用dao层中UserDao接口中的抽象方法。
在这里插入图片描述
先写一个Userservice接口:

public interface UserService {
    void getUser();
}

写一个UserService接口的实现类:

//想要在业务层中调用dao层中的方法
public class UserServiceImpl implements UserService {

    //调用dao层中的方法,就要首先new实现类的对象
    //1.我想使用mysql数据库
    private UserDao userDao = new UserDaoMySqlImpl();
    public void getUser() {
       userDao.getUser();
    }
}
第三步:写一个测试类,测试一下

我们在测试类中创建Service层中的接口的对象,然后调用Service层中的方法

public class MyTest {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        userService.getUser();
    }
}

在这里插入图片描述

出现了问题:程序的耦合性太强

完成上面的程序以后,我们思考一个问题:我在UserServiceImpl类中调用了UserDaoMySqlImpl实现类,那么如果我想调用UserDaoOracleImpl实现类呢?
又或者想调用UserDaoSqlSever实现类呢?
那么就会出现下面的问题:

//想要在业务层中调用dao层中的方法
public class UserServiceImpl implements UserService {

    //调用dao层中的方法,就要首先new实现类的对象
    //1.我想使用mysql数据库
    //private UserDao userDao = new UserDaoMySqlImpl();
    
    //2.我想使用Oracle数据库
    //private UserDao userDao1 = new UserDaoOracleImpl();
    
    //3.我想使用SqlServer数据库
    private UserDao userDao2 = new UserDaoSqlServerImpl();

    public void getUser() {
       //userDao.getUser();
       //userDao1.getUser();
       userDao2.getUser();
    }
}

我想使用换个类调用就会重新修改代码,代码的耦合性太强,这不是我们想要的结果。。

问题来了,如何进行改进?
有两种改进方法:

1.使用setter方法改进

下面我们再写一个UserService接口的实现类:UserServiceImpl2
在这个实现类中我们加入一个setter方法

public class UserServiceImpl2 implements UserService {
    //使用多态机制
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void getUser() {
        userDao.getUser();
    }
}

然后重新写一个测试类,看一下有哪些好处:

public class MyTest2 {
    public static void main(String[] args) {
        UserServiceImpl2 userService = new UserServiceImpl2();
        //1.我想使用mysql数据库
        userService.setUserDao(new UserDaoMySqlImpl());
        userService.getUser();
		//2.我想使用SqlServer数据库
        userService.setUserDao(new UserDaoSqlServerImpl());
        userService.getUser();
		//3.我想使用Oracle数据库
        userService.setUserDao(new UserDaoOracleImpl());
        userService.getUser();
    }
}

通过改进后可以发现,程序的耦合性降低了,不需要再修改service层中的代码,只需要在测试类中修改就好。

2.使用构建函数改进

本质上和setter方法形同,不再赘述

public class UserServiceImpl3 implements UserService {

    //使用多态机制
    private UserDao userDao;

    public UserServiceImpl3(UserDao userDao) {
        this.userDao = userDao;
    }

    public void getUser() {
        userDao.getUser();
    }
}
public class MyTest3 {
    public static void main(String[] args) {
        UserServiceImpl3 userService = 
                new UserServiceImpl3(new UserDaoMySqlImpl());
        userService.getUser();
        
        userService = new UserServiceImpl3(new UserDaoOracleImpl());
        userService.getUser();
    }
}

赞(0) 打赏
未经允许不得转载:IDEA激活码 » 【Spring学习及总结03】何为IOC(控制反转)??

相关推荐

  • 暂无文章

一个分享Java & Python知识的社区