zoukankan      html  css  js  c++  java
  • spring的DI.IoC是什么

    最近要搞spring的单元测试,不得已啊啊啊啊啊啊啊啊啊又要开始搞spring……

    日目晶……

    搞这几个概念,先甩一部分代码:

    UserDao 接口

    package com.itheima.ioc;
    public interface UserDao {
    	public void say();
    }
    

     

    该接口实现类UserDaoImpl 

    package com.itheima.ioc;
    public class UserDaoImpl implements UserDao {
    	@Override
    	public void say() {
    		// TODO Auto-generated method stub
    		System.out.println("userDao say hello world");
    	}
    }
    

     

    • 控制反转的概念

    在一般的设计中,如果要调用UserDaoImpl的say()方法,就要new一个UserDaoImpl类出来,比如以下的方法:

    ……
    UserDaoImpl userDao = new UserDaoImpl();
    userDao.say();
    ……  

    在spring中呢,有个概念叫IoC(Inversion  of Control 即控制反转),它通过框架设定,可以通过配置文件,在spring的容器(可以理解为一个装满了对象的瓶子)中取一个现成的UserDaoImpl的实例出来,而不需要new一个。

    具体做法:

    编辑applicationContext.xml,添加一个userDao的bean(可以理解为一个类,添加之后,spring容器中就有这个类的对象)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans ……>
    	<!-- 添加UserDaoImpl实例,id=userDao -->
    	<bean id = "userDao" class = "com.itheima.ioc.UserDaoImpl"/>
    </beans>
    

      

    调用userDaoImpl的say()方法代码如下:

    package com.itheima.ioc;
    /**
     * 通过Spring容器来获取实现类对象
     * 而不是通过new
     */
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    public class TestIoc {
    	public static void main(String[] args) {
    		ClassPathXmlApplicationContext applicationContext = 
    				new ClassPathXmlApplicationContext("applicationContext.xml");
    		UserDao userDao = (UserDao) applicationContext.getBean("userDao");
    		userDao.say();
    	}
    }
    

      

    • 依赖注入的概念

    UserService代码:

    package com.itheima.ioc;
    public interface UserService {
    	public void say();
    }
    

     

    UserServiceImpl 实现类:

    这里的实现类中,我们要重写say()方法,say()方法有一个现成的UserDaoImpl方法,我们直接拿过来用,一般是这么写的:

    public class UserServiceImpl implements UserService {
    	UserDao userDao=new UserDaoImpl();
    	public void setUserDao(UserDao userDao){
    		this.userDao= userDao;
    	}
    	@Override
    	public void say() {
    		// TODO Auto-generated method stub
    		this.userDao.say();
    		System.out.println("userService say hello world~");
    	}
    }
    

     

    这么写没问题,不过spring容器里面有个现成的UserDaoImpl,还new一个,很浪费,直接拿过来用会更方便。

    这个直接拿过来用的搞法,叫DI(Dependency Injection ,即依赖注入)。

    依赖注入有两种做法,一个是setter,一个是构造方法,这里只给setter的方法,构造方法的我看的书上还没讲,不想动。

    做法如下:

    改写UserServiceImpl,把new变成私有属性

    public class UserServiceImpl implements UserService {
    	//声明UserDao属性
    	private UserDao userDao ;
    	
    	public void setUserDao(UserDao userDao){
    		this.userDao= userDao;
    	}
    	@Override
    	public void say() {
    		// TODO Auto-generated method stub
    		this.userDao.say();
    		System.out.println("userService say hello world~");
    	}
    }
    

      

    编写配置文件,把userDao Bean添加到userService下面:

    <beans xmlns="……">
    	<bean id = "userDao" class = "com.itheima.ioc.UserDaoImpl"/>
    	<bean id = "userService" class = "com.itheima.ioc.UserServiceImpl">
    	<!-- 将id=userDao的实例注入到userSericeImpl -->
    		<property name="userDao" ref = "userDao"/>
    	</bean>
    </beans>
    

      

     

     

     

    总结:

    1.将new转化为从容器中拿,这就是IoC的工作机制,即控制反转+依赖注入,这两个概念可以理解为同一个东西

    2.控制权由硬代码new一个实体类,转移到spring容器分配,即为控制反转;

    3.spring负责将容器内的对象,注入给调用者,即为依赖注入。

      

  • 相关阅读:
    PowerDesigner15在win7-64位系统下对MySQL反向工程
    像竹子一样有节操
    spring 注解
    如何实现在已有代码之后添加逻辑之java动态代理
    如何实现在已有代码之后添加逻辑之继承,组合(静态代理)实现方法
    MySql按周,按月,按日分组统计数据
    SpringBoot 获取前端传递Json的几种方法
    Spring boot 基础整理(一)
    layui常用插件(二) 时间插件
    layui常用插件(一) 轮播图
  • 原文地址:https://www.cnblogs.com/zhizhiyin/p/10669635.html
Copyright © 2011-2022 走看看