首页 > 编程语言 >Java面试题:你知道Spring的IOC吗?那么,它为什么这么重要呢?

Java面试题:你知道Spring的IOC吗?那么,它为什么这么重要呢?

时间:2024-04-28 10:34:21浏览次数:26  
标签:面试题 Java 对象 Spring 使用 IOC public 注入

Spring的IOC(控制反转)是一种设计模式,它允许开发者将对象的创建和管理交给Spring框架来完成。在Spring中,IOC允许开发者将对象依赖关系从代码中分离出来,从而使代码更加灵活、可重用和易于管理。

IoC 全称Inverse of Control(反向控制或控制反转)。

在类和类之间存在控制权,控制权指的是对象的创建和使用,比如有类A和类B,我们之前的做法是在A中调用B,那么控制权就在A中,这样做的耦合度较高,如果修改了 B,A也要做相应修改。

class A {

} 

class B {
  // B需要将A的实例new出来,也就是我们说的控制 private A a = new A();
  public void use() {      
    System.out.print(a);
  }
}

 

引入Spring框架后,控制权由 spring 容器来负责。当A想使用B时,需要由 Spirng容器通过配置文件进行注入。这种思想就是IoC(为了更好的理解,我们可以这样认为,对象创建和使用的控制权转移到了Spring容器,由Spring容器来控制)。

// 说明A自己控制自己,把自己初始化出来,注入给了容器 
@Component 
class A {

}

class B {
   // B不需要控制a,直接使用。如果A没有把自己注入给容器,B就不能使用
   @Resource private A a;

   public void use() {
        System.out.print(a);
   }
}

 

实现Spring的IOC(控制反转)有以下几种方式

  • 使用@Autowired注解:这是Spring中最常用的实现IOC的方式。通过在需要依赖注入的类上使用@Autowired注解,Spring会自动将依赖对象注入到该类中。

  • 使用配置文件:通过在Spring配置文件中定义bean,可以手动创建和管理对象。这种方式适合于需要灵活控制对象创建和生命周期的情况。

  • 使用Java配置:通过使用Java配置类,可以更灵活地定义bean和配置对象之间的关系。这种方式适合于需要更细粒度控制的情况。

 

如何实现一个简易的IOC功能?

上述是Spring容器简单的使用IOC功能,如果我们自己想实现一个简单版的,可以按照以下步骤:

  • 定义一个容器类,用于管理对象的创建和注入。

  • 实现对象的创建方法,可以使用常见的工厂模式或依赖查找等方式来创建对象。

  • 在容器类中定义一个注入方法,用于将对象注入到需要依赖的对象中。


下面是一个简单的代码示例,展示了如何实现一个简易的IOC功能:

// 定义容器类
public class ObjectContainer {
  // 创建对象的方法
  public static Object createObject(String className) throws Exception {
    // 使用反射创建对象
    return Class.forName(className).newInstance();
  }

  // 注入对象的方法
  public static void injectObject(Object target, String className) throws Exception {
    // 将对象注入到目标对象中
    Field field = target.getClass().getField(className);
    field.set(target, ObjectContainer.createObject(className));
  }
}

// 使用示例
public class ExampleClass {
  private Object obj; // 需要注入的对象

  public ExampleClass(String className) {
    try {
      // 注入对象
      ObjectContainer.injectObject(this, className);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void doSomething() {
    // 使用对象进行操作
    obj.method();
  }
}

 

在上面的示例中,我们定义了一个ObjectContainer类,它包含了创建对象和注入对象的方法。在ExampleClass中,我们使用了ObjectContainer的注入方法将对象注入到目标对象中。使用时只需要传入对象的类名即可。

请注意,上述示例只是一个简单的实现,没有考虑一些复杂的场景,例如循环依赖、类型转换等问题。在实际开发中,需要根据具体的需求和场景进行适当的调整和优化。

使用IOC有哪些好处?

①、使用者不用关心引用Bean的实现细节,譬如对于B b = new A(c,d,e,f);来说,如果B要使用A,那还要 把c,d,e,f侈个类全都感知一遍,这显然是非常麻烦且不合理的。

②、不用创建多个相同的bean导致浪费,仍然是: 

A b = new A();
A c = new A();

如果B和C都引用了A,那么B和C就可能new两个A实例,实际上,我们只需要一个就好了。 

③、Bean的修改使用方无需感知。同样是上面的例子,假如说Bean A需要修改,如果没有IOC的话,所有引用到A的其他Bean都需要感知这个逻辑,并且做对应的修改。但是如果使用了IOC,其他Bean就完全不用感知到。

 

标签:面试题,Java,对象,Spring,使用,IOC,public,注入
From: https://www.cnblogs.com/marsitman/p/18163209

相关文章

  • 不推荐把“线程”注入到Spring、在线程中使用Spring的Bean的方法
    一、不推荐把“线程”注入到spring将线程注入到Spring容器中并不是一个常见的做法,而且通常也不推荐这样做,原因如下:生命周期管理困难:Spring管理的Bean生命周期由Spring容器管理,而线程的生命周期由JVM管理。将线程注入到Spring容器中会导致线程的生命周期与Spring容器的生命周......
  • SpringBoot中几种好用的代码生成器(基于Mybatis-plus生成entity、mapper、xml等)
    前言熟悉Spring框架的同学一定都知道MVC开发模式吧,控制器(Controller)、业务类(Service)、持久层(Repository)、数据库映射(Mapper)、各种DO类构成了我们服务端的代码。初学的时候,觉得新鲜手写这些东西不觉得有啥,但是写久了就会觉得很烦。好不容易在数据库中写完了一遍字段,在Java代码又要......
  • 【FileZillaServer用网络驱动器作为主目录时,客户端无法列出文件】【Spring Boot安装成
    遇到的两个问题安装FileZillaServer后,把映射的网络驱动器内容作为主目录时,客户端能正常登录,但是无法列出文件。把本机的某个目录组为主目录,客户端可以正常列出文件。把SpringBoot安装成Windows服务时,访问系统中映射的网络驱动器失败(开发过程中能够正常访问,通过命令的方式......
  • Spring Boot 编写 API 的 10条最佳实践
    10个最佳实践,让您像专业人士一样编写SpringBootAPI,并结合编码示例和解释:1.RESTfulAPI设计原则:清晰一致的资源命名:使用准确反映API管理的资源的名词(例如,/products、/users)。@GetMapping("/products/{id}")publicResponseEntity<Product>getProductById(@PathVaria......
  • Java中的读写锁ReentrantReadWriteLock详解,存在一个小缺陷
    写在开头最近是和java.util.concurrent.locks包下的同步类干上了,素有并发根基之称的concurrent包中全是精品,今天我们继续哈,今天学习的主题要由一个大厂常问的Java面试题开始:小伙子,来说一说Java中的读写锁,你都用过哪些读写锁吧?这个问题小伙伴们遇到了该如何回答呢?心里琢磨去......
  • 短视频开发,如何用Java实现短信验证码?
    背景Java是一种短视频开发时比较流行的编程语言,验证码是一种常用的网络安全技术。Java发展至今,网上也出现了各种各样的验证码,本人初学Java,下面是我用Java实现短信验证码的总结。截图展示实现代码短视频开发后台接收前台的kgCaptchaToken进行验证,验证成功执行成功......
  • SpringMVC(1)-@RequestMapping的简单使用
    本文核心内容来自于韩顺平老师的课程@RequestMapping注解可以用来指定控制器或者处理器的某个方法的请求url@ControllerpublicclassUserServlet{@RequestMapping("/login")publicStringlogin(){return"login";}}1@RequestMappi......
  • SpringBoot常用注解(部分)
     @Service:注解在类上,表示这是一个业务层bean@Controller:注解在类上,表示这是一个控制层bean@Repository:注解在类上,表示这是一个数据访问层bean@Component:注解在类上,表示通用bean,value不写默认就是类名首字母小写@Autowired:按照类型(Spring容器默认单例模......
  • [Java]线程生命周期与线程通信
    【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)https://www.cnblogs.com/cnb-yuchen/p/18162522出自【进步*于辰的博客】线程生命周期与进程有诸多相似,所以我们很容易将两者关联理解并混淆,一些细节之处确有许多不同,因为线程调度与进程调度虽都由CPU完成,但两者并......
  • Java 多线程初步总结
    Java多线程程序,进程,线程的基本概念:程序:是为了完成特定的任务,使用某种语言编写的一组指令的集合,是一段静态的代码,静态对象,如Excel,World等。进程:是程序的一次执行多次,或者是正在运行的一个程序,是一个动态的过程,有自身的产生,存在和消亡的过程,即存在生命周期。线程:进程可以进一步......