一、什么是Spring IOC容器

Spring是包含众多工具的IoC容器,控制反转即IoC,它有两个核心的功能:

①将对象(Bean)存储在容器(Spring)

②将对象(Bean)从容器(Spring)中取出来

【扩展:将对象存放到容器中的好处】

将对象存储在 IoC 容器相当于将以后可能⽤的所有工具制作好都放到仓库中,需要的时候直接取就行了,用完再把它放回到仓库。而new 对象的方式相当于,每次需要工具了,才现做,用完就扔掉了也不会保存,下次再用的时候还得重新做,这就是 IoC 容器和普通程序开发的区别

二、IOC有哪些优点

IOC 或 依赖注入把应用的代码量降到最低

它使应用容易测试,单元测试不再需要单例和JNDI查找机制

最小的代价和最小的侵入性使松散耦合得以实现

IOC容器支持加载服务时的饿汉式初始化和懒加载

三、控制反转(IOC)有什么作用

将创建对象的控制权交给Spring的IoC,以前需要程序员自己控制对象创建,现在交给Spring的IoC创建,如果需要使用需要通过DI(依赖注入)@Autowired自动注入

解耦,由容器去维护具体的对象,降低耦合度

【扩展:什么是解耦,代码示例】

解耦指的是解决了代码的耦合性,耦合性也可以换⼀种叫法叫程序相关性。这就好比我们打造⼀辆完整的汽车,如果所有的配件都是自己造,那么当客户需求发生改变的时候,比如轮胎的尺寸不再是原来的尺寸了,那我们要自己动手来改了,但如果我们是把轮胎外包出去,那么即使是轮胎的尺寸发生变变了,我们只需要向代理工厂下订单就行了,我们自身身是不需要出力的

在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire

改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car

public class IocCarExample {
   public static void main(String[] args) {
     Tire tire = new Tire(20);
     Bottom bottom = new Bottom(tire);
     Framework framework = new Framework(bottom);
     Car car = new Car(framework);
     car.run();
  }
  //车类,把创建⼦类的⽅式,改为注⼊传递的⽅式
  static class Car {
    private Framework framework;
    public Car(Framework framework) {
      this.framework = framework;
    }
    public void run() {
      framework.init();
    }
  }
  //车身类
  static class Framework {
    private Bottom bottom;
    public Framework(Bottom bottom) {
      this.bottom = bottom;
    }
    public void init() {
    bottom.init();
    }
  }

四、IoC和DI有什么区别

IoC:控制反转,由主动new产生对象(耦合过高)转换成从外部提供对象,就是将对象的创建控制权从程序转移到了外部

DI:依赖注入,就是在程序运行期间,自动的将一个对象从Spring拿出来给当前类使用

区别:

IoC 是“目标”也是⼀种思想,而目标和思想只是⼀种指导原则,而 DI 就是具体的实现

例如:比如说我今天心情比较好,吃⼀顿好的犒劳犒劳自己,那么“吃⼀顿好的”是思想和目标(是 IoC),但最后我是吃海底捞,这就是具体的实现,就是 DI

五、Spring IoC的实现机制

1. 简单工厂:通过一个方法传入一个标识,生产对应对象

工厂模式案例:

public static void main(String[] arge){
  // 调用工厂方法,根据传入参数,返回一个对象
  BaseService  userService = Factory.getBean("user");
}
class Factory{
  public static BaseService getBean(String beanName){
      if("user".equals(beanName)){
         return = new UserServiceImpl();
      }
      if("role".equals(beanName)){
         return = new RoleServiceImpl();
      }
   }
}

2.反射:反射就是在工厂模式getBean()方法中通过反射的方式来创建Bean

class Factory {
    public static Fruit getInstance(String ClassName) {
        Fruit f=null;
        try {
            f=(Fruit)Class.forName(ClassName).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }
}

【扩展:反射是什么,反射的实现原理】

反射机制是在运行的状态,对于任何一个类,都能知道所有属性和方法,对于任何一个对象都能调用任意方法属性,所以反射就是将Java类的各种成分映射成一个个对象

①通过Class类的静态方法:forName(String className)(常用)获取Class对象

 try {
   Class stuClass3 = Class.forName("fanshe.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
   System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  }

②通过反射获取构造方法并使用:

public class Student {
  //---------------构造方法-------------------
 //(默认的构造方法)
 Student(String str){
  System.out.println("(默认)的构造方法 s = "   str);
 }
 //无参构造方法
 public Student(){
  System.out.println("调用了公有、无参构造方法执行了。。。");
 }
 
 //有一个参数的构造方法
 public Student(char name){
  System.out.println("姓名:"   name);
 }
 //有多个参数的构造方法
 public Student(String name ,int age){
  System.out.println("姓名:" name "年龄:"  age);//这的执行效率有问题,以后解决。
 }
 //受保护的构造方法
 protected Student(boolean n){
  System.out.println("受保护的构造方法 n = "   n);
 }
 //私有构造方法
 private Student(int age){
  System.out.println("私有的构造方法   年龄:"  age);
 }
 
}

六、IoC支持哪些功能

Spring 的 IoC 设计支持以下功能:

1.依赖注入

2.依赖检查

3.自动装配

4.支持集合

5.指定初始化方法和销毁方法

6.支持回调某些方法(但是需要实现 Spring 接口,略有侵入)

其中,最重要的就是依赖注入,从 XML 的配置上说,即 ref 标签。对应 Spring RuntimeBeanReference 对象。

对于 IoC 来说,最重要的就是容器。容器管理着 Bean 的生命周期,控制着 Bean 的依赖注入

【扩展:解释Bean周期】下篇博客详细介绍

七、BeanFactory和ApplicationContext有什么区别

首先创建Spring上下文的时候,会使用BeanFactory和ApplicationContext两种方法

//先得到Spring上下文
  ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");//配置文件对应
 // 先得到 spring 获取 bean 的对象
  BeanFactory beanFactory =
                new XmlBeanFactory(new ClassPathResource("spring-config.xml"));

共同点:BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口

区别:

①继承关系和功能:ApplicationContext是BeanFactory的子类,BeanFactory只是提供了基础操作Bean的方法,ApplicationContext除了继承了 BeanFactory 的所有功能之外,它还拥有独特的特性,还添加了对国际化⽀持,资源访问⽀持等

②性能:ApplicationContext 是⼀次性加载并初始化所有的 Bean 对象,而 BeanFactory是需要那个才去加载那个,因此更加轻量

八、ApplicationContext通常的实现是什么

FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数

ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置

WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean

九、依赖注入的方式,构造器依赖注入和 Setter方法注入的区别

依赖注入是时下最流行的IoC实现方式,依赖注入分为接口注入,Setter方法注入,和构造器注入,三种方式。其中接口注入由于在灵活性和易用性比较差,现在从Spring4开始已被废弃

1.构造器注入

将被依赖对象通过构造函数的参数注入给依赖对象,并且在初始化对象的时候注入。优点:对象初始化完成后便可获得可使用的对象。

缺点:当需要注入的对象很多时,构造器参数列表将会很长;不够灵活。若有多种注入方式,每种方式只需注入指定几个依赖,那么就需要提供多个重载的构造函数,麻烦

2.setter方法注入

lOC Service Provider通过调用成员变量提供的setter函数将被依赖对象注入给依赖类优点:灵活,可以选择性地注入需要的对象

缺点:依赖对象初始化完成后由于尚未注入被依赖对象,因此还不能使用

3.接口注入

依赖类必须要实现指定的接口,然后实现该接口中的一个函数,该函数就是用于依赖注入。该函数的参数就是要注入的对象

优点:接口注入中,接口的名字、函数的名字都不重要,只要保证函数的参数是要注入的对象类型即可。缺点:侵入行太强,不建议使用

【扩展:什么是侵入性?】

如果类A要使用月别人提供的一个功能,若为了使用这功能,需要在自己的类中增加额外的代码,这就是侵入性

区别:

十、依赖注入的基本原则和优点

依赖注入的基本原则:

应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应该由IoC容器负责,“查找资源”的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责。容器全权负责组件的装配,它会把符合依赖关系的对象通过属性(JavaBean中的setter)或者是构造器传递给需要的对象

优势:

①查找定位操作与应用代码完全无关

②不依赖于容器的API,可以很容易地在任何容器以外使用应用对象

③不需要特殊的接口,绝大多数对象可以做到完全不必依赖容器

以上就是深入了解Spring控制反转IOC原理的详细内容,更多关于Spring控制反转IOC的资料请关注Devmax其它相关文章!

深入了解Spring控制反转IOC原理的更多相关文章

  1. Spring JdbcTemplate执行数据库操作详解

    JdbcTemplate是Spring框架自带的对JDBC操作的封装,目的是提供统一的模板方法使对数据库的操作更加方便、友好,效率也不错,这篇文章主要介绍了Spring JdbcTemplate执行数据库操作,需要的朋友可以参考下

  2. Spring Batch批处理框架操作指南

    Spring Batch 是 Spring 提供的一个数据处理框架。企业域中的许多应用程序需要批量处理才能在关键任务环境中执行业务操作,这篇文章主要介绍了Spring Batch批处理框架操作指南,需要的朋友可以参考下

  3. Spring详细讲解@Autowired注解

    @Autowired注解可以用在类属性,构造函数,setter方法和函数参数上,该注解可以准确地控制bean在何处如何自动装配的过程。在默认情况下,该注解是类型驱动的注入

  4. 使用Spring AOP实现用户操作日志功能

    这篇文章主要介绍了使用Spring AOP实现了用户操作日志功能,功能实现需要一张记录日志的log表,结合示例代码给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. Spring Security认证器实现过程详解

    一些权限框架一般都包含认证器和决策器,前者处理登陆验证,后者处理访问资源的控制,这篇文章主要介绍了Spring Security认证器实现过程,需要的朋友可以参考下

  6. spring学习JdbcTemplate数据库事务管理

    这篇文章主要为大家介绍了spring学习JdbcTemplate数据库事务管理,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  7. Spring Boot 集成Redisson实现分布式锁详细案例

    这篇文章主要介绍了Spring Boot 集成Redisson实现分布式锁详细案例,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下

  8. 使用Selenium控制当前已经打开的chrome浏览器窗口

    有时通过selenium打开网站时,发现有些网站需要扫码登录,就很头疼,导致爬虫进展不下去,下面这篇文章主要给大家介绍了关于使用Selenium控制当前已经打开的chrome浏览器窗口的相关资料,需要的朋友可以参考下

  9. Spring Security实现接口放通的方法详解

    在用Spring Security项目开发中,有时候需要放通某一个接口时,我们需要在配置中把接口地址配置上,这样做有时候显得麻烦。本文将通过一个注解的方式快速实现接口放通,感兴趣的可以了解一下

  10. 如何利用Spring把元素解析成BeanDefinition对象

    这篇文章主要介绍了如何利用Spring把元素解析成BeanDefinition对象,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下

随机推荐

  1. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  3. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  4. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  5. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  6. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  7. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  8. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  9. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Spring JdbcTemplate执行数据库操作详解

    JdbcTemplate是Spring框架自带的对JDBC操作的封装,目的是提供统一的模板方法使对数据库的操作更加方便、友好,效率也不错,这篇文章主要介绍了Spring JdbcTemplate执行数据库操作,需要的朋友可以参考下

返回
顶部