首页 > 其他分享 >IOC&DI

IOC&DI

时间:2024-10-16 10:10:00浏览次数:3  
标签:依赖 DI Spring Bean 使用 注解 IOC 注入

 IOC 

springboot自动创建对象,并存起来

  • Inversion of Control控制反转

    • 对象的创建权限交给Spring,并把创建好的对象存到容器里(其实就是一个map集合)

DI 

  • Dependency Injection

    • 自动注入放到IOC容器中的对象

    • 实际就是给属性自动赋值

Bean对象

  • 存到IOC容器里的对象都叫Spring Bean对象

  • 使用IOC和DI时,
    Bean对象的创建和获取都和IOC容器有关
    Bean对象之间搭配使用

哪些类适合控制反转和依赖注入? 

  • 控制器类(Controller)-

    • Spring MVC是Spring框架的一部分,它提供了一个基于模型-视图-控制器(MVC)的Web应用程序开发架构。在Spring MVC中,控制器类负责处理客户端请求并返回响应。通过将控制器类交给Spring管理,可以方便地实现请求的映射、参数绑定、异常处理等功能。

  • 服务类(Service)

    • 在应用程序中,服务类负责处理业务逻辑。将服务类交给Spring管理可以实现依赖注入、事务管理等功能。使用Spring的依赖注入功能,可以方便地将依赖的类注入到服务类中,从而实现松耦合和可测试性。同时,Spring的事务管理功能可以确保服务类中的数据库操作具有一致性和完整性。

  • 数据访问对象(DAO)

    • DAO类负责处理数据库的操作。通过将DAO类交给Spring管理,可以方便地使用Spring的事务管理功能和持久化框架(如Hibernate或MyBatis)来简化数据库操作。此外,Spring还提供了一些便捷的功能,如异常转换和批量更新,用于简化数据库访问的代码

  • 工具类

    • 工具类通常包含一些辅助方法,用于完成特定的功能。通过将工具类交给Spring管理,可以方便地在其他类中使用这些方法,避免手动创建对象。

  • AOP切面(Aspect)

    • DAO类负责处理数据库的操作。通过将DAO类交给Spring管理,可以方便地使用Spring的事务管理功能和持久化框架(如Hibernate或MyBatis)来简化数据库操作。此外,Spring还提供了一些便捷的功能,如异常转换和批量更新,用于简化数据库访问的代码

  • 配置类(Configuration)

    • DAO类负责处理数据库的操作。通过将DAO类交给Spring管理,可以方便地使用Spring的事务管理功能和持久化框架(如Hibernate或MyBatis)来简化数据库操作。此外,Spring还提供了一些便捷的功能,如异常转换和批量更新,用于简化数据库访问的代码

 

如何在Spring中使用控制反转和依赖注入?

1.控制反转注解 

  • @Component

    • 普通类上加上该注解即可实现IOC

    • 组合特化注解

      • @Controller

      • @RestController

      • @Service

      • @Mapper

      • @Repository

2.依赖注入注解 

  • 依赖注入注解

    • @Resource 属性注入优先使用@Resource(默认按照Bean名字从容器中获取,默认的springBean名字时类对应的小驼峰)

      • 默认Bean名字注入

    • @Autowired

      • 默认Bean类型注入

    • @Primary(解决Bean重名问题)

      • 指定注入Bean优先级

    • @Qualifier(解决Bean重名问题)

      • 指定Bean的名字

 

3.组合注解@SpringBootApplication 

 面试题

1.说说SpringBoot加载启动流程

1. 入口类

  • 启动类通常是用 @SpringBootApplication 注解的类。这个注解结合了 @Configuration@EnableAutoConfiguration@ComponentScan 三个注解。

  • 通过 public static void main(String[] args) 方法调用 SpringApplication.run() 启动应用。

2. 创建 SpringApplication 实例

  • SpringApplication 是 Spring Boot 应用的核心类。调用 run() 方法时,它会创建一个 ApplicationContext 实例。

3. 准备环境

  • 在创建 ApplicationContext 之前,Spring Boot 会准备应用环境(Environment),比如读取配置文件(application.propertiesapplication.yml)和命令行参数。

4. 创建 ApplicationContext

  • Spring Boot 默认使用 AnnotationConfigApplicationContextWebApplicationContext(对于 Web 应用),并根据配置创建适当的上下文。

5. 自动配置

  • 启用自动配置机制。@EnableAutoConfiguration 会根据类路径中的库自动配置 Spring 应用的各个部分(如数据源、Spring MVC、缓存等)。

  • Spring Boot 使用 spring.factories 文件来加载自动配置类。

6. Bean 创建和初始化

  • 扫描组件并创建 Bean。@ComponentScan 注解会扫描指定包及其子包中的组件(如 @Service@Repository@Controller 等)。

  • 在此过程中,所有的 Bean 会被创建并初始化,包括执行 @PostConstruct 注解的方法。

7. 加载 ApplicationRunner 和 CommandLineRunner

  • 在上下文初始化完成后,Spring Boot 会执行所有实现了 ApplicationRunnerCommandLineRunner 接口的 Bean,以便在应用启动后执行一些逻辑。

8. 启动嵌入式服务器

  • 对于 Web 应用,Spring Boot 会启动嵌入式服务器(如 Tomcat、Jetty 或 Undertow),并将应用部署到服务器上。

9. 应用就绪

  • 最后,Spring Boot 应用启动完成,处于就绪状态,开始接受请求。

总结

Spring Boot 的启动过程通过自动配置和约定优于配置的方式,大大简化了 Spring 应用的配置和启动流程,使得开发者能够快速构建和部署应用。如果你需要更详细的某个步骤或相关技术的解释,可以告诉我!

2.说说SpringIOC控制反转流程

3.如何进行依赖注入

4.说说Spring中用到类哪些设计模式

在 Spring 中,使用了多种设计模式,以实现灵活性、可扩展性和可维护性。常见的设计模式包括:

  1. 单例模式(Singleton)

    • Spring 默认的 Bean 范围是单例的,即每个 Bean 在 Spring 容器中只有一个实例。这种模式确保了全局访问同一个对象。
  2. 工厂模式(Factory)

    • Spring 使用工厂模式来创建和管理 Bean。BeanFactoryApplicationContext 是工厂类,负责创建和配置 Bean。
  3. 代理模式(Proxy)

    • Spring AOP(面向切面编程)广泛使用代理模式,通过动态代理(JDK 动态代理和 CGLIB)来实现方法拦截和增强功能。
  4. 模板方法模式(Template Method)

    • 在 Spring JDBC 和 Spring MVC 中使用了模板方法模式,提供一个模板(如 JdbcTemplateRestTemplate),用户只需实现某些步骤的具体细节。
  5. 观察者模式(Observer)

    • Spring 事件机制基于观察者模式,允许应用程序发布和订阅事件。ApplicationEventApplicationListener 是相关的类。
  6. 策略模式(Strategy)

    • Spring 通过接口和实现类组合来实现策略模式。例如,使用 HandlerMappingHandlerAdapter 来处理不同类型的请求。
  7. 装饰者模式(Decorator)

    • Spring 的 AOP 可以看作是一种装饰者模式,通过增强现有类的功能而不改变其结构。
  8. 责任链模式(Chain of Responsibility)

    • 在 Spring MVC 中,处理请求的多个过滤器和拦截器可以看作是责任链模式。每个拦截器可以选择继续处理或终止请求。
  9. 适配器模式(Adapter)

    • Spring 的许多组件(如 JdbcTemplateDataSource)使用适配器模式,使得不同的实现可以互操作。

通过这些设计模式,Spring 提供了灵活的架构和可扩展的功能,帮助开发者快速构建和维护应用程序。

5.说说Springboot开发中的常见注解以及作用?

在 Spring Boot 开发中,常见的注解及其作用包括:

  1. @SpringBootApplication:该注解是一个组合注解,包含了 @Configuration@EnableAutoConfiguration@ComponentScan,用于标记主配置类,启动 Spring Boot 应用。

  2. @RestController:结合了 @Controller@ResponseBody,用于创建 RESTful 控制器,处理 HTTP 请求并返回 JSON 数据。

  3. @RequestMapping:用于映射 HTTP 请求到相应的处理方法,可以指定请求路径、请求方法等。

  4. @GetMapping、@PostMapping、@PutMapping、@DeleteMapping:这些是 @RequestMapping 的快捷方式,分别用于处理 GET、POST、PUT 和 DELETE 请求。

  5. @Autowired:用于自动注入依赖,可以标记在构造器、字段或 setter 方法上。

  6. @Component:标记一个类为 Spring 管理的组件,Spring 会自动检测并注册该类为 Bean。

  7. @Service:用于标记服务层的组件,通常用于业务逻辑处理。

  8. @Repository:用于标记数据访问层的组件,通常用于持久化逻辑。

  9. @Configuration:用于定义 Spring 的配置类,通常包含 Bean 的定义。

  10. @Value:用于注入外部配置(如 application.properties 或 application.yml)中的值。

  11. @Profile:用于指定 Bean 在特定环境下的激活条件,常用于区分开发、测试和生产环境。

  12. @Transactional:用于声明事务,标记在类或方法上,控制事务的边界。

这些注解帮助简化配置和开发,使 Spring Boot 应用更加易于管理和扩展。理解它们的作用和用法,有助于提高开发效率。

6.说说@Resource与@Autowire的区别

@Resource

属性注入优先使用@Resource
默认按照Bean名字从容器中获取
默认的springBean名字时类对应的小驼峰
不同包下有可能存在同名类
解决办法->

@Component注解在创建Bean的时候指定名字

@Resource从ioc容器获取时也指定名字

 

DI:从ioc容器中获取已经创建好的对象给属性(成员变量)赋值
给一个类的属性(成员变量)赋值 有几种方式:四种
1.直接等于号赋值
2.构造器
3.set方法
4.反射
@Autowired 一般使用在构造器赋值和set方法赋值时
所以收SpringDi注入有三种方式
字段(属性)DI ->@Resource
构造器DI      -> @Autowired
set方法DI    -> @Autowired
@Resource 与  @Autowired使用:
如果一个SpringBean类中值需要注入很少的其他的Bean对象->优先使用@Resource
如果一个SpringBean类中值需要注入很多的其他的Bean对象->优先使用@Autowired

7.使用 springbean时要注意的问题

1.非bean不能调用bean

2.不能形成循环依赖->如何解决

在 Spring Boot 中,循环依赖问题指的是两个或多个 Bean 互相依赖,导致依赖无法被正确注入。这种情况可能导致应用程序在启动时抛出异常。常见的解决循环依赖的方法包括以下几种:

1. 使用 @Lazy 注解

可以在其中一个或多个 Bean 的依赖上使用 @Lazy 注解,这样 Spring 容器在第一次需要这个 Bean 时才会创建它,从而打破循环依赖。

@Component
public class A {
    private final B b;

    @Autowired
    public A(@Lazy B b) {
        this.b = b;
    }
}

2. 使用 setter 注入

如果使用构造器注入导致循环依赖,可以考虑使用 setter 注入。这样,Spring 可以在 Bean 初始化后再注入依赖。



@Component
public class A {
    private B b;

    @Autowired
    public void setB(B b) {
        this.b = b;
    }
}

 

3. 拆分循环依赖

如果可能的话,重新设计你的类结构,避免循环依赖。例如,将某些通用的功能提取到一个独立的 Bean 中,或者考虑是否可以通过事件机制来解耦。

4. 使用 @PostConstruct@EventListener

有时候,你可以延迟某些依赖的初始化直到所有 Bean 完全初始化后,这样可以避免循环依赖。例如,你可以在一个 Bean 的 @PostConstruct 方法中手动注入另一个 Bean。

@Component
public class A {
    private B b;

    @Autowired
    public A() {
        // No injection in constructor to avoid circular dependency
    }

    @Autowired
    public void setB(B b) {
        this.b = b;
    }

    @PostConstruct
    public void init() {
        // Do something after all beans are initialized
    }
}

5. 使用 ObjectFactoryProvider 接口

通过注入 ObjectFactoryProvider 来延迟获取依赖的实例,从而打破循环依赖。

@Component
public class A {
    private final ObjectFactory<B> bFactory;

    @Autowired
    public A(ObjectFactory<B> bFactory) {
        this.bFactory = bFactory;
    }

    public void someMethod() {
        B b = bFactory.getObject();  // Lazily fetch B when needed
    }
}

6. 避免循环依赖的设计

从设计层面上避免循环依赖通常是最理想的解决方案。通过仔细分析你的类之间的依赖关系,重构代码以去除循环依赖。

7. 构造器注入中无法解决的情况

如果使用构造器注入并且无法重构代码,考虑用工厂模式或引入中间层来拆分依赖链。

小结

Spring 默认支持 setter 注入的循环依赖处理,但在使用构造器注入时,如果遇到循环依赖,需要考虑使用延迟加载、重构代码结构或者使用依赖注入的其他高级特性来解决这个问题。最好还是从设计上避免循环依赖,这样可以减少复杂性和潜在的错误。

 


标签:依赖,DI,Spring,Bean,使用,注解,IOC,注入
From: https://www.cnblogs.com/freps/p/18469227

相关文章

  • Loading class `com.mysql.jdbc.Driver’. This is deprecated. The new driver class
    原文链接:Loadingclass`com.mysql.jdbc.Driver’.Thisisdeprecated.Thenewdriverclassis`com.mysql.cj.jdbc.Driver’.–每天进步一点点(longkui.site)某日构建springboot项目时,报的错:Loadingclass`com.mysql.jdbc.Driver'.Thisisdeprecated.Thenewdriver......
  • DevEco Studio实时检查
    辑器会实时的进行代码分析,如果输入的语法不符合编码规范,或者出现语义语法错误,将在代码中突出显示错误或警告,将鼠标放置在错误代码处,会提示详细的错误信息。从DevEcoStudio4.0Release版本开始,当compatibleSdkVersion≥10时,编辑器代码实时检查支持ArkTS性能语法规范检查。说......
  • DevEco Studio:代码code Linter检查
    CodeLinter代码检查CodeLinter针对ArkTS/TS代码进行最佳实践/编程规范方面的检查。检查规则支持配置,配置方式请参考配置代码检查规则。开发者可根据扫描结果中告警提示手工修复代码缺陷,或者执行一键式自动修复,在代码开发阶段,确保代码质量。检查方法:在已打开的代码编辑器窗......
  • Codeforces Round 978 (Div. 2) C. Gerrymandering 轮廓DP
    CodeforcesRound978(Div.2)C轮廓DPC.Gerrymandering思路:考虑有哪些情况呢?发现结尾只有三种情况,0.平的,1.上凸,2.下凸。那么每一种后面能出现什么呢?这样看起来就好写啦。//AConemoretimes//nndbk#include<bits/stdc++.h>usingnamespacestd;typedeflonglo......
  • DirectoryOpus插件:“照得标管理器”-海量照片分类管理好帮手!
       照得标管理器前言  名词解释:“照得标管理器”,即:照片得到标签管理器,后文统一简称“照得标管理器”或“照得标”。  注:请不要和抖音上的“奥德彪”、“王德发”之类联系,我分享的是正经照片-得到-标签-管理器。  有段时间作者赋闲在家,决定把留在电脑上的几万张......
  • 【推荐 - 源码安装】Redis - 安装
    准备查看操作系统位数[root@lab10~]#getconfLONG_BIT64查看gcc编译环境[root@lab10~]#gcc-vUsingbuilt-inspecs.COLLECT_GCC=gccCOLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapperTarget:x86_64-redhat-linuxConfiguredwith:......
  • DevEco Studio代码阅读
    DevEcoStudio支持使用多种语言进行应用/服务的开发,包括ArkTS、JS和C/C++。在编写应用/服务阶段,可以通过掌握代码编写的各种常用技巧,来提升编码效率。代码高亮支持对代码关键字、运算符、字符串、类、标识符、注释等进行高亮显示,您可以打开【DevEcoStudio>Preferences】(Wind......
  • Contextualization Distillation from Large Language Model for Knowledge Graph Com
    文章目录题目摘要简介相关工作语境化提取实验结论限制附录题目用于知识图完成的大型语言模型的语境化提取论文地址:https://aclanthology.org/2024.findings-eacl.32/项目地址:https://github.com/davidli0406/contextulization-Distillation摘要    ......
  • 【做题记录】Codeforces Round 943 (Div. 3)/CF1968A-F
    【做题记录】CodeforcesRound943(Div.3)/CF1968A-FA暴力枚举即可。B双指针枚举即可,能匹配就匹配。C考虑构造出\(a[1]=1,a[i]=a[i-1]+x[i]\)的数列,发现满足要求。D有个明显的结论,两人最终一定是在某个点上的。于是从起点开始扫一遍,求出到每一个点的距离和路上的分数......
  • ssh-add 报错:Error connecting to agent No such file or directory
    问题描述在添加SSH时报错Errorconnectingtoagent:Nosuchfileordirectory解决方法1.打开PowerShell管理员身份打开WindowsPowerShell2.查看服务是否启动get-servicessh*3.启动服务Set-Service-Namessh-agent-StartupTypeManualStart-Servicessh......