精华内容
下载资源
问答
  • ioc和di
    2021-08-06 20:40:37

    在学习spring框架的过程中一定会学过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,下面是我对IoC(控制反转) 、DI(依赖注入)的理解。
    一、IOC是 什么?
    IOC的英文名字是Inversion of Control,IOC即“控制反转”,不是什么技术,而是一种设计思想。在Java 开发 中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
    ①所谓控制,指的是管理对象的权利;
    ②所谓反转,指的是由Spring管理而不是开发者管理
    二、IOC的作用
    IoC的其中一个目的是为了解耦合,当将一个对象交给第三方容器管理后,那么对象之间的耦合相较于传统 new方式会降低。同时Spring IoC也可以降低对象的管理成本,比如实现单例模式(默认即是单例)等等。
    要注意的是,IoC和DI的关系并不是一个,类似于接口和实现类的区别,IoC是一种设计思想,DI是IoC 的一 种实现,DI也称为依赖注入,在Spring中可以通过@Autowired注解将Spring容器中的对象注入到指 定的位置。
    三、依赖注入(DI)
    (1)相对于IoC而言,依赖注入(DI)更加准确地描述了IoC的设计理念。所谓依赖注入(Dependency Injection), 即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关 系的目标对象 实例注入到应用系统中的各个关联的组件之中。组件不做定位查询,只提供普通的Java方 法让容器去决定 依赖关系。
    (2)Spring框架使用这种方式。依赖注入是时下最流行的IoC实现方式,依赖注入分为接口注入(Interface Injection),Setter方法注入(Setter Injection)和构造器注入(Constructor Injection)三种方式。 其中接口注入由于在灵活性和易用性比较差,现在从Spring4开始已被废弃。
    (3)依赖注入的基本原则是:应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应 该由 IoC 容器负责,“查找资源”的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责。容器全 权负 责组件的装配,它会把符合依赖关系的对象通过属性(JavaBean中的setter)或者是构造器传递给需 要的对象。
    (4)依赖注入之所以更流行是因为它是一种更可取的方式:让容器全权负责依赖查询,受管组件只需要暴 露JavaBean的setter方法或者带参数的构造器或者接口,使容器可以在初始化时组装对象的依赖关系。 其与依赖查找方式 相比,主要优势为:
    1、查找定位操作与应用代码完全无关。
    2、不依赖于容器的API,可以很容易地在任何容器以外使用应用对象。
    3、不需要特殊的接口,绝大多数对象可以做到完全不必依赖容器。
    四、IOC和DI之间的关系
    依赖注入不能单独存在,需要在ioc的基础上完成操作。也就是说,只有把对象创建了,你才能向类里面注入值。

    更多相关内容
  • springIOC和DI

    2017-05-08 11:48:59
    什么是spring,spring核心,spring优点,spring体系结构, 入门案例,DI基础,核心API,文档内附代码
  • spring IOC和DI 理解

    2021-11-15 11:51:25
    IOC(控制反转)和DI(依赖注入)是spring中的重要组成部分,下面是个人的一些理解,不代表官方。 1、IOC是什么? IOC:全名是Inversion of Controller 中文解释是控制反转,不是什么技术,是一种设计思想。在java...

    IOC(控制反转)和DI(依赖注入)是spring中的重要组成部分,下面是个人的一些理解,不代表官方。

    1、IOC是什么?

    IOC:全名是Inversion of Controller 中文解释是控制反转,不是什么技术,是一种设计思想。在java开发中IOC意味着你设计好的对象交给容器控制,而不是传统的在你对象内部直接控制。如何理解好IOC那?理解IOC的关键是要明确:“谁控制谁”、“控制什么”、为何是反转(有反转就应该有正转)哪些方面反转了,我们来分析一下:

    1)谁控制谁,控制什么:传统的java SE程序设计,我们直接在对象内部new进行创建对象,是程序主动去创建对象,而IOC有专门的容器来创建这些对象,即由IOC容器来控制对象的创建;谁控制谁?当然是IOC容器控制对象,控制什么?主要是控制外部资源的获取(不只是对象包括比如文件等)。

    2)为何是反转,那方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中直接获取依赖对象,也就是正转;而反转是由容器来帮忙创建和注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取反转了。

    用图例说明一下,传统程序设计如下图1,都是主动去创建相关对象然后再组合起来:

            

    当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了,如图2所示

     

     

    2、IOC(控制反转)做什么用?

    IOC不是一种技术,是一种设计思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由程序内部主动创建对象依赖,从而导致类与类之间高耦合,难于测试;有了IOC容器后,把创建和查找依赖对象的控制权交给了容器,由容器注入组合对象,所以对象和对象之间是松耦合的,这样利于测试,也利于功能复用,更重要的是使得程序的整个体系结构变的非常灵活。

    其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。
    IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

    3、DI是什么?
     DI:Dependency Injection ,即依赖注入:是组件之间依赖关系由容器在运行期决定,形象的说,由容器动态的将某个依赖关系注入到组件之中。

    4、DI(依赖注入)有什么用

    依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

    理解DI的关键:谁依赖谁,为什么需要依赖,谁注入谁,注入了什么?

    1)谁依赖谁:当然是应用程序依赖IOC容器

    2)为什么需要依赖:应用程序需要IOC容器来提供对象需要的外部资源

    3)谁注入谁:IOC容器注入应用程序的某个对象,应用程序依赖的对象

    4)注入了什么:注入某个对象依赖的外部资源(包括对象,资源,常来数据)

    IoC和DI什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。
     

    5、怎么用?

    整体如图:

     

    代码如下:

    1、Servelt转ApplicationContext:(1)获取applicationContext上下文(2)初始化handlerMapper

    package com.zmc.spring.framework.webmvc.servlet;
    
    import com.zmc.spring.framework.annotation.MCController;
    import com.zmc.spring.framework.annotation.MCRequestMapping;
    import com.zmc.spring.framework.annotation.MCRequestParam;
    import com.zmc.spring.framework.context.MCApplicationContext;
    
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.lang.annotation.Annotation;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author zhangmc
     * @create 2021/11/9 17:01
     */
    public class MCDispatcherServlet extends HttpServlet{
    
        //IOC容器的访问上下文
        private MCApplicationContext mcApplicationContext = null;
    
        //控制端Controller方法和url 的对应关系
        public Map<String,Method> handlerMap = new HashMap<String, Method>();
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            this.doPost(req,resp);
        }
    
        @Override
        protected void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{
            try {
                doDispatch(req,resp);
            }catch (Exception e){
                e.printStackTrace();
                resp.getWriter().write("500 Exception,Detail: " + Arrays.toString(e.getStackTrace()));
            }
        }
    
        private void doDispatch(HttpServletRequest req,HttpServletResponse resp) throws Exception{
            String url = req.getRequestURI();
            String contextPath = req.getContextPath();
    
            url = url.replaceAll(contextPath,"").replaceAll("/+","/");
            //判断路径是否存在
            if(!this.handlerMap.containsKey(url)){
                resp.getWriter().write("404 Not Find!!!");
                return ;
            }
            
            //获取方法
            Method method = this.handlerMap.get(url);
            
            //1、先把形参的位置和参数的名字建立映射关系,并且缓存下来
            Map<String,Integer> paramIndexMapping = new HashMap<String, Integer>();
    
            Annotation[][] pa = method.getParameterAnnotations();
            //遍历
            for (int i = 0;i<pa.length;i++){
                for (Annotation an : pa[i]){
                    //判断是否是MCRequestParam
                    if(an instanceof MCRequestParam){
                        //强转
                        String paramName = ((MCRequestParam)an).value();
                        //过滤""
                        if(!"".equals(paramName.trim())){
                            paramIndexMapping.put(paramName,i);
                        }
                    }
                }
            }
    
            Class<?>[] parameterTypes = method.getParameterTypes();
            for (int i = 0; i<parameterTypes.length;i++){
                Class<?> parameType = parameterTypes[i];
                if(parameType == HttpServletRequest.class || parameType == HttpServletResponse.class){
                    paramIndexMapping.put(parameType.getName(),i);
                }
            }
    
            //2、根据参数位置匹配参数名字,从url中取到参数名字对应的值
            Object[] paramValues = new Object[parameterTypes.length];
    
            Map<String,String[]> params = req.getParameterMap();
    
            //http://localhost/web/query.json?name=MC&name=TT
            for (Map.Entry<String,String[]> entry : params.entrySet()){
                String value = Arrays.toString(entry.getValue())
                        .replaceAll("\\[|\\]","")
                        .replaceAll("\\s","");
    
                if(!paramIndexMapping.containsKey(entry.getKey())){
                    continue;
                }
    
                int i = paramIndexMapping.get(entry.getKey());
    
                //涉及到类型强制转换
                paramValues[i] = value;
            }
    
            if(paramIndexMapping.containsKey(HttpServletRequest.class.getName())){
                int i = paramIndexMapping.get(HttpServletRequest.class.getName());
                paramValues[i] =  req;
            }
    
            if(paramIndexMapping.containsKey(HttpServletResponse.class.getName())){
                int i = paramIndexMapping.get(HttpServletResponse.class.getName());
                paramValues[i] = resp;
            }
            
            String beanName =toLowerFirstCase(method.getDeclaringClass().getSimpleName());
            //3、组成动态实际参数列表,传给反射调用
            method.invoke(mcApplicationContext.getBean(beanName),paramValues);
            
    
        }
    
        @Override
        public void init(ServletConfig config) throws ServletException{
    
            mcApplicationContext = new MCApplicationContext(config.getInitParameter("contextConfigLocation"));
    
            //========MVC功能=======
            //初始化handlerMapper
            doInitHandlerMapper();
    
            System.out.println("MC spring framework is init.");
        }
    
        //初始化controller方法和url路径
        private void doInitHandlerMapper(){
            if(this.mcApplicationContext.getBeanDefinitionCount() == 0){
                return;
            }
    
            for (String beanName : this.mcApplicationContext.getBeanDefinitionNames()){
                Object instance = mcApplicationContext.getBean(beanName);
                Class<?> clazz = instance.getClass();
                //判断类是否是Controller注解
                if(!clazz.isAnnotationPresent(MCController.class)){
                    continue;
                }
    
                String baseUrl = "";
                if(clazz.isAnnotationPresent(MCRequestMapping.class)){
                    MCRequestMapping mcRequestMapping = clazz.getAnnotation(MCRequestMapping.class);
                    baseUrl = mcRequestMapping.value();
                }
    
                if(null == clazz.getMethods()){
                    continue;
                }
    
                //取类中的方法
                for (Method method : clazz.getMethods()){
                    //取方法注解 判断是否是requestMapping
                    if(!method.isAnnotationPresent(MCRequestMapping.class)){
                        continue;
                    }
                    MCRequestMapping requestMapping = method.getAnnotation(MCRequestMapping.class);
    
                    String requestUrl = ("/"+baseUrl+"/"+requestMapping.value()).replaceAll("/+","/");
    
                    handlerMap.put(requestUrl,method);
    
                    System.out.println("Mappred :" + requestUrl + "------>"+method);
                }
    
    
            }
    
        }
    
        private String toLowerFirstCase(String simpleName){
            char[] chars = simpleName.toCharArray();
            chars[0]+=32; //利用了ASCII码,大写字母和小写字母相差32这个规律
            return String.valueOf(chars);
        }
    
    }
    

    2、ApplicationContext 上下文对象

     

    package com.zmc.spring.framework.context;
    
    import com.zmc.spring.framework.annotation.MCAutowried;
    import com.zmc.spring.framework.annotation.MCController;
    import com.zmc.spring.framework.annotation.MCService;
    import com.zmc.spring.framework.beans.MCBeanWrapper;
    import com.zmc.spring.framework.beans.config.MCBeanDefinition;
    import com.zmc.spring.framework.beans.support.MCBeanDefinitionReader;
    import com.zmc.spring.framework.beans.support.MCDefaultListableBeanFactory;
    import com.zmc.spring.framework.core.MCBeanFactory;
    
    import java.lang.reflect.Field;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @author zhangmc
     * @create 2021/11/9 18:10
     */
    public class MCApplicationContext implements MCBeanFactory{
    
        private MCDefaultListableBeanFactory registry = new MCDefaultListableBeanFactory();
    
        //三级缓存(终极缓存) key beanName(类名) value BeanWrapper包装类
        private Map<String,MCBeanWrapper> factoryBeanInstanceCache = new HashMap<String, MCBeanWrapper>();
    
        //key 类名 value 反射的实例对象
        private Map<String,Object> factoryBeanObjectCache = new HashMap<String, Object>();
    
        private MCBeanDefinitionReader reader;
    
        public MCApplicationContext(String... configLocations) {
    
            //1、加载配置文件
            reader = new MCBeanDefinitionReader(configLocations);
    
            try {
                //2、解析配置文件,把所有的配置信息封装成BeanDefinition对象
                List<MCBeanDefinition> beanDefinitions = reader.loadBeanDefinitions();
                //3、所有的配置信息缓存起来
                this.registry.addBeanDefinitionMap(beanDefinitions);
                //4、加载非延迟加载的所有Bean
                doLoadInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private void doLoadInstance(){
            //循环调用getBean()
            for (Map.Entry<String,MCBeanDefinition> entry : this.registry.beanDefinitionMap.entrySet()){
                String beanName = entry.getKey();
                if(!entry.getValue().isLazyInit()){
                    getBean(beanName);
                }
            }
        }
    
    //    @Override
        public Object getBean(Class className) {
            return getBean(className.getName());
        }
    
        //从IOC容器中获取一个Bean对象
    //    @Override
        public Object getBean(String beanName) {
            //1、先拿到BeanDefinition对象
            MCBeanDefinition beanDefinition = registry.beanDefinitionMap.get(beanName);
            if(beanDefinition == null){
                return null;
            }
            //2、反射实例化对象
            Object instance = instantiateBean(beanName,beanDefinition);
    
            //3、将返回的对象封装到BeanWrapper
            MCBeanWrapper beanWrapper = new MCBeanWrapper(instance);
    
            //4、执行依赖注入
            populateBean(beanName,beanDefinition,beanWrapper);
    
            //5、保存到IOC容器中
            this.factoryBeanInstanceCache.put(beanName,beanWrapper);
    
            return beanWrapper.getWrapperInstance();
        }
    
        //反射实例化对象
        private Object instantiateBean(String beanName,MCBeanDefinition beanDefinition){
            String className = beanDefinition.getBeanClassName();
            Object instance = null;
            try {
                //jvm查找 并加载指定的类
                Class<?> clazz = Class.forName(className);
                //通过反射得到实例化对象
                instance = clazz.newInstance();
    
                //如果是代理对象,触发AOP的逻辑
    
                this.factoryBeanObjectCache.put(beanName,instance);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return instance;
        }
    
        private void populateBean(String beanName,MCBeanDefinition beanDefinition,MCBeanWrapper beanWrapper){
            //获取实例化对象
            Object instance = beanWrapper.getWrapperInstance();
            //获取加载类
            Class<?> clazz = beanWrapper.getWrapperClass();
            //判断是否是Controller和Service的注解
            if(!(clazz.isAnnotationPresent(MCController.class) || clazz.isAnnotationPresent(MCService.class))){
                return;
            }
            //遍历 忽略字段的修饰符 不管你是 private / protected / public / default
            for (Field filed : clazz.getDeclaredFields()){
                //过滤非Autowired注解的
                if(!filed.isAnnotationPresent(MCAutowried.class)){
                    continue;
                }
                MCAutowried  autowried= filed.getAnnotation(MCAutowried.class);
                String autowriedBeanName = autowried.value().trim();
                if("".equals(autowriedBeanName)){
                    autowriedBeanName = filed.getType().getName();
                }
    
                //代码反射面前就是裸奔
                //强制访问 强吻
                filed.setAccessible(true);
    
                try {
                    if(this.factoryBeanInstanceCache.get(autowriedBeanName) == null){
                        continue;
                    }
    
                    //相当于 demo.action.MyAction.
                    filed.set(instance,this.factoryBeanInstanceCache.get(autowriedBeanName).getWrapperInstance());
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public int getBeanDefinitionCount(){
            return this.registry.beanDefinitionMap.size();
        }
    
        public String[] getBeanDefinitionNames(){
            return this.registry.beanDefinitionMap.keySet().toArray(new String[0]);
        }
    }
    

        

    参考:浅谈对Spring IOC以及DI的理解_luoyepiaoxue2014的博客-CSDN博客_ioc和di

    展开全文
  • 理解Spring中的IoC和DI

    千次阅读 2020-12-28 21:27:58
    什么是IoC和DIIoC(Inversion of Control 控制反转):是一种面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度。其基本思想是:借助于“第三方”实现具有依赖关系的对象之间的解耦。DI(Dependence ...

    什么是IoC和DI

    IoC(Inversion of Control 控制反转):是一种面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度。其基本思想是:借助于“第三方”实现具有依赖关系的对象之间的解耦。

    DI(Dependence Injection 依赖注入):将实例变量传入到一个对象中去(Dependency injection means giving an object its instance variables)。

    控制反转是一种思想

    依赖注入是一种设计模式

    IoC框架使用依赖注入作为实现控制反转的方式

    为什么需要

    在没有IoC之前,我们要在A类中使用B类,就要在A类中new出B类的实例,这样A类和B类之间就出现了耦合。

    public class A {

    private B b = new B();

    }

    使用了IoC之后,我们就把实例化这样操作交给框架去帮我们做了。

    Spring 中的IoC

    容器是Spring的核心,Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系。

    Spring容器并不是只有一个,Spring自带多个容器的实现,可以归纳为两种不同的类型:

    bean工厂(BeanFactory),最简单的容器,提供基本的DI支持。

    应用上下文(ApplicationContext),继承了BeanFactory,并提供应用框架级别的服务。

    作为开发人员,我们需要告诉Spring哪些对象要作为bean装配到容器中,bean和bean之间的依赖关系。Spring提供了三种主要的装配机制:

    隐式的bean发现机制和自动装配

    在Java中进行显示配置

    在XML中进行显示配置

    下面我们逐一介绍这三种机制。

    自动装配bean

    组件扫描:spring会自动发现应用上下文中所创建的bean

    @Component 注解表明该类会作为组件类,并告知Spring要为这个类创建bean。

    @Component

    public class Dog {

    }

    @ComponentScan 注解启用了组件扫描。

    @Configuration

    @ComponentScan

    public class DemoApplication {

    }

    自动装配:Spring自动满足bean之间的依赖

    @Autowired 注解可以作用在构造器、方法、属性上。

    @Component

    public class Dog {

    // 属性

    @Autowired

    private Cat cat;

    // 构造器

    // 从Spring 4.3开始,具有单个构造函数的类可以省略@Autowired注释

    @Autowired

    public Dog(Cat cat) {

    this.cat = cat;

    }

    // 方法

    @Autowired

    public void setCat(Cat cat) {

    this.cat = cat;

    }

    }

    在Java中装配bean

    组价配置:声明一个配置类,并在配置类中配置bean

    @Configuration 注解表明这个类是配置类,我们可以在配置类下创建bean。

    @bean 注解会告诉Spring这个方法将会返回一个对象,该对象要注册为Spring上下文中的bean。

    /**

    * 普通类

    */

    public class BaseBean {

    public void p() {

    System.out.println("Hello bean");

    }

    }

    /**

    * 配置类

    */

    @Configuration

    public class BeanConfig {

    // 这个方法返回一个对象,Spring会把这个对象注册为bean

    @Bean

    public BaseBean getBaseBean() {

    return new BaseBean();

    }

    }

    组件注入:在配置类中把被依赖的组件注入另一个组件中

    两种方式注入bean:

    我们可以直接调用get方法,获取到对应的组件

    在get方法中把被依赖的组件作为参数传入,Spring在调用这个方法时,会自动为你注入。

    /**

    * 普通类

    */

    public class BaseBean {

    public void p() {

    System.out.println("Hello bean");

    }

    }

    /**

    * 普通类

    */

    public class UserBean {

    private BaseBean baseBean;

    public UserBean(BaseBean baseBean) {

    this.baseBean = baseBean;

    }

    }

    /**

    * 配置类

    */

    @Configuration

    public class BeanConfig {

    // 这个方法返回一个对象,Spring会把这个对象注册为bean

    @Bean

    public BaseBean getBaseBean() {

    return new BaseBean();

    }

    /**

    * 以下为两种注入bean的方法

    */

    // 方法一:直接调用get方法

    @Bean

    public UseBean getUseBean() {

    return new UseBean(getBaseBean());

    }

    // 方法二:当做参数传入,Spring将自动为你注入

    @Bean

    public UseBean getUseBean(BaseBean baseBean) {

    return new UseBean(baseBean);

    }

    }

    通常情况下我们都会使用方法二。

    通过XML装配bean

    尽管现在我们已经不再怎么使用XML装配bean,但在Spring刚刚出现的时候,XML是描述配置的主要方式,我们还是有必要了解一下的。

    在使用JavaConfig的时候,我们创建了一个配置类来装配bean,而在XML配置中,我们需要创建一个XML文件,并且要以元素为根。

    最为简单的Spring XML配置如下所示:

    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">

    组件配置

    以上文的BaseBean为例,我们在XML文件中把它声明为bean。

    组件注入

    c:_="baseBean" />

    XML的语法我就不再这里详述了,有兴趣的同学可以自行学习。

    总结

    本文我们简单介绍了Spring中的IoC,介绍了Spring中装配bean的三种方式:自动化配置,基于Java的显式配置以及基于XML的显式配置。这些技术都是为了描述Spring应用中的组件以及组件之间的关系。

    一般来说我们都会使用自动化配置,尽量避免显式配置带来的维护成本。如果不得不使用显式配置的话,我们优先选择基于Java的配置,它比基于XML的配置更加强大、类型安全并且易于重构。

    参考资料

    展开全文
  • IOC和DI的区别

    2021-10-12 16:21:44
    先从字面上理解一下什么是IOC,什么是DI IOC:Inversion of Control,我们一般叫做控制反转,这是一种技术思想,反转了什么控制,我的理解就是反转了对象创建以及管理的控制权,交给了外部环境,在Spring中具体的...

    先从字面上理解一下什么是IOC,什么是DI

    IOC:Inversion of Control,我们一般叫做控制反转,这是一种技术思想,反转了什么控制,我的理解就是反转了对象创建以及管理的控制权,交给了外部环境,在Spring中具体的体现简单描述就是把创建对象的控制权交给了Spring框架,由Spring框架来做一整套的对象创建,管理等流程,而如果没有Spring框架或者说是没有采用IOC这种技术思想的话,在维护对象之间的依赖关系时在维护我们一般都是手动new对象,这样会导致系统中对象之间耦合过高,不利于项目的扩展和修改,说白了,主要还是为了解耦。

    DI:Dependancy Injection,依赖注入,注入什么,注入对象,维护对象之间的关系,比如说A对象中有依赖B对象,换做以前的做法,我们会手动new出B对象设置到A对象中,但是我们开发的实际场景都是强调面对接口编程,这样代码扩展性才好,试试想下,我们可以直接new接口么,肯定不行,因为new的时候如果不实现接口中的方法就肯定会报错,所以此时真正会new的是该接口的实现类,之后业务变动了,原来的实现类不符合要求了,此时我们为该接口重新编写了实现类,所以要一一修改每个有new出旧的实现类的地方,想想就觉得麻烦,所以我们把该接口的实现类实例交给容器管理,我们只需要用@Autowired注解在接口类上,Spring容器自然会为我们找到该接口类的实现类,然后注入到有依赖的类中。简单的描述DI的作用,就是IoC容器会自动帮对象找到相应的依赖对象并注入,不需要对象主动去找(手动new),因此我们不需要关心具体的实现类,面向接口编程就好。

    聊聊区别

    首先我们要明白IOC和DI要达成的目标是一致的,那就是解决对象创建以及对象依赖关系维护的耦合问题,其次它们解决该问题的角度有所不同,IOC从对象方面着手,先把对象的创建和管理等一系列操作权统一交给了容器,控制权反转,IOC容器现在才是
    老大,那么接下来DI要做的就是从容器方面着手,要求容器自动把对象的依赖对象注入到对象中,完成依赖注入,做到解耦,同时还做到了组件的复用,想想平时的service实例,dao实例,这些无状态的类,只需要维护一份在IOC容器就好了,大家共用即可。

    聊聊理解

    个人的感觉,我倒是不觉得IOC和DI概念会混淆,我觉得它们是互相合作的那种,IOC完成了解决对象耦合问题的前置条件,那就是不再把一些对象的控制权给开发者,而是全权交给IOC容器,然后IOC容器才能在此基础上,做到自动调度容器中的对象,帮助完成对象间的依赖关系维护,做到了DI,怎么说呢,我觉得它们都是为了一个目标,但是就不是一个东西,怎么会混淆。

    PS:以上只是个人的理解,仅提供参考,就当做个笔记,后续理解深了会再试试修改。

    展开全文
  • 主要介绍了Spring IOC和DI实现原理及实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • Spring - 关于IOC和DI的一些个人理解

    千次阅读 2021-08-04 16:31:04
    网上不乏一些高质量关于IOCDI理解的文章,这里限于个人能力低微,就不做些贻笑大家的事了,只是结合自己的情况整理下各路大佬们通俗易懂的解释。 Bromon的blog上对IoCDI浅显易懂的讲解 IOC作为Spring的标志象征...
  • 3. IoC和DI简介

    2022-03-08 18:39:27
    IoC和DI简介一. 控制反转依赖注入1. IoC的核心设计思想2. IoC---Inversion of Control---控制反转3. DI---Dependency Injection---依赖注入二. IoC功能中的三个常用接口实现类1. BeanFactory接口2. ...
  • IOC和DI 的区别

    2021-10-17 19:18:30
    DI的意思是依赖注入 ,前者是目的更偏向于实际操作相比于传统的通过new的方式来创建对象并手动的为属性赋值这些行为完全交于程序员控制,IOC则是把创建对象并给对象中的属性赋值交由sprin工厂管理,从而达到控制反转...
  • IOC和DI的关系

    千次阅读 2021-04-19 19:44:26
    IOC(控制反转) 全称为:Inverse of Control .将对在自身对象中的一个内置对象的控制反转,反转后不再由自己本身的对象进行控制这个内置对象的创建,...IOC和DI的关系 ioc就是容器,di就是注入这一行为,那么di确实
  • Spring中的IOC和DI

    千次阅读 2020-12-19 00:40:28
    一、IOC介绍IoC(Inverse of Control:控制反转)是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。IoC 容器是 Spring 用来实现 IoC 的载体, IoC 容器实际上就是个Map(key,value),Map...
  • dI.Hook - 使用 AOP 的轻量级 IoC DI 引擎 dI.Hook(发音为 du'hʊk)是一个轻量级的 IoC DI 引擎,通过代码或配置定义钩子,动态或有条件地调用它们,并在不需要时处理它们。 然而,这不是另一个依赖注入...
  • 对于Spring而言,就是由Spring来控制对象的生命周期对象之间的关系;IoC还有另外一个名字——“依赖注入(Dependency Injection)”。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,即由...
  • spring的ioc和di

    2022-02-15 22:26:08
    1、IOC和DI IOC: 控制反转 即控制权的转移,将我们创建对象的方式反转了,以前对象的创建是由我们开发人员自己维护,包括依赖关系也是自己注入。使用了spring之后,对象的创建以及依赖关系可以由spring完成创建以及...
  • Spring的IOC和DI(带例子,超级详解)

    千次阅读 多人点赞 2019-10-10 13:07:15
    1、什么是IOC?(Inversion Of Controll 控制反转) 控制反转是面向对象编程中的一种设计原则,可以用来降低计算机代码之间的耦合度,其中最常见的方式是依赖注入,还有一种方式是依赖查找(Dependency Lookup),...
  • 什么是IoC DI

    2021-01-16 20:13:54
    IoC 即控制反转,DI即依赖注入 简单来说,IoC是一种思想,而DI是这种思想的具体实现方式 2.深入了解 要了解控制反转( Inversion of Control ), 有必要先了解软件设计的一个重要思想:依赖倒置原则(Dependency ...
  • IoC和DI的区别

    千次阅读 2019-06-09 11:22:58
    首先我们一般回答面试题都是先说出他们两个是什么,然后在说他们之间...2.DI:Dependency Injection,翻译过来就是:依赖注入。是指spring框架在创建bean对象时,动态的将依赖对象注入到bean组件中 原来在使用Spr...
  • 注意:本文章依据黑马程序员的SSM框架视频编写而成。 目录 前言 一、IoC是什么? ...1.通过配置文件告知IoC容器要管理...理解Spring框架中IoC和DI的概念,这么做的好处有哪些。 一、IoC是什么? IoC(Inversion....
  • 一、什么是IOCInversion of Control(控制反转),字面上的理解是说这个事物的控制权不在于你了,而在于其他人手上了。举个列子说明,比如超市收银员,以前收银员自己去通过输入商品编码、价格、结算、收钱等工作;...
  • Spring IOC和DI之间的关系

    千次阅读 2019-06-30 16:34:59
    我们通过小故事来理解IOC和DI的关系 现实生活中,比如想吃水饺,在没有水饺店的日子里,最直观的做法就是:买面粉、蔬菜、肉等等食材,再去制造也就是去煮熟。这些都是主动创建的过程。也就是说想吃一顿水饺需要...
  • spring的IoC和DI详解

    2020-08-28 23:28:50
    主要介绍了spring的IoC和DI详解,还是挺不错的,这里分享给加,需要的朋友可以参考下。
  • Spring IOC和DI的理解

    千次阅读 2020-05-22 18:03:53
    Spring框架中离不开Spring的IoC(控制反转) 、DI(依赖注入),这里从IOC是什么、IOC能做什么、IOC和DI的区别三个方面介绍下IOC和DI。 一、IOC是什么 IOC:Inversion Of Control,控制反转。它是一种设计思想,将你设计...
  • Spring中的IoC和DI介绍

    2020-09-28 22:10:25
    1. IoC控制反转:把对象的创建权限交给Spring容器,让spring帮我们实例化对象,我们只是从spring容器中取得实例 2. DI依赖注入:依赖了spring容器注入的那个对象,需要调用setXXX方法 2.1扩展:注入属性 2.1.1...
  • 首先,我们要知道IOC和DI是什么: Ioc中文翻译叫控制反转,Ioc是一种设计思想。Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。 在传统的java程序开发中,我们直接在对象内部通过...
  • IoC和DI是什么

    2020-07-10 08:27:26
    IoC叫控制反转,是Inversion of Control的缩写,DI(Dependency Injection)叫依赖注入,是对IoC更简单的诠释。控制反转是把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配管理。...
  • .NET Core中的IoC和DI

    2019-11-14 15:29:47
    1 本期文章介绍IoC和DI的简单含义IoC的理解与认知DI的理解与认知IoCDI的关系使用IoC/DI的好处在.NET Core中使用IoC/DI本文示例代码下载地址​2 往期文章使用LayUI+EFCore+AutoMapper+LINQ完成一个简单的增删改查...
  • spring的IOC和DI理解

    2019-10-07 22:05:58
    1.1 要想理解 IoC DI 就必须搞清楚如下的问题: 参与者都有谁? 依赖:谁依赖谁?为什么需要依赖? 注入:谁注入于谁?到底注入什么? 控制反转:谁控制谁?控制什么?为何叫反转? 依赖注入控制反转是同...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 66,940
精华内容 26,776
关键字:

ioc和di

友情链接: beyesi.rar