首页 > 其他分享 >Web基础-分层解耦-IOC&Dl详解

Web基础-分层解耦-IOC&Dl详解

时间:2025-01-13 10:28:45浏览次数:3  
标签:Web Dl Resource Autowired bean 注解 IOC 注入

(回顾重点)Q:什么是IOC以及DI?

控制反转: Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。

依赖注入: Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。

Bean对象:IOC容器中创建、管理的对象,称之为Bean。 

IOC详解:

回顾一下三层架构:

在之前的入门案例中,要把某个对象交给IOC容器管理,需要在类上添加一个注解:@Component而Spring框架为了更好的标识web应用程序开发当中,bean对象到底归属于哪一层,又提供了 

@Component的衍生注解:

注解

说明

位置

@Component

声明bean的基础注解

不属于以下三类时,用此注解(一般是pojo下的实体类)

@Controller

@Component的衍生注解

标注在控制层类上

@Service

@Component的衍生注解

标注在业务层类上

@Repository

@Component的衍生注解

标注在数据访问层类上(由于与mybatis整合,用的少) 

注意1:声明bean的时候,可以通过注解的value属性指定bean的名字,如果没有指定,默认为类名首字母小写。

注意2:使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。(规定必须遵守)

补充:@RestController的底层已经封装过了@controller注解,所以不用单独添加注解。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 * @since 4.0.1
	 */
	@AliasFor(annotation = Controller.class)
	String value() default "";

}

组件扫描:

问题:使用前面学习的四个注解声明的bean,一定会生效吗?

答案:不一定。(原因:bean想要生效,还需要被组件扫描)

  • 前面声明bean的四大注解,要想生效,还需要被组件扫描注解 @ComponentScan 扫描。

  • 该注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解(细节)

  • @SpringBootApplication 中,默认扫描的范围是启动类所在包及其子包。(重点)超出这个范围的bean都将扫描不到。

所以,在项目开发中,只需要按照如上项目结构,将项目中的所有的业务类,都放在启动类所在包的子包中,就无需考虑组件扫描问题。


DI详解:

依赖注解DI的细节

依赖注入,是指IOC容器要为应用程序去提供运行时所依赖的资源,而资源指的就是对象。

我们可以使用了@Autowired这个注解,完成依赖注入的操作;

而这个Autowired翻译过来叫:自动装配。@Autowired注解,默认是按照类型进行自动装配的(去IOC容器中找某个类型的对象,然后完成注入操作)

入门程序举例:在EmpController运行的时候,就要到IOC容器当中去查找EmpService这个类型的对象,而我们的IOC容器中刚好有一个EmpService这个类型的对象,所以就找到了这个类型的对象完成注入操作。

@Autowired用法

 @Autowired 进行依赖注入,常见的方式,有如下三种:

1). 属性注入

@RestController
public class UserController {

    //方式一: 属性注入
    @Autowired
    private UserService userService;
    
  }
  • 优点:代码简洁、方便快速开发。

  • 缺点:隐藏了类之间的依赖关系、可能会破坏类的封装性。

2). 构造函数注入

@RestController
public class UserController {

    //方式二: 构造器注入
    private final UserService userService;
    
    @Autowired //如果当前类中只存在一个构造函数, @Autowired可以省略
    public UserController(UserService userService) {
        this.userService = userService;
    }
    
 }   
  • 优点:能清晰地看到类的依赖关系、提高了代码的安全性。

  • 缺点:代码繁琐、如果构造参数过多,可能会导致构造函数臃肿。

  • 注意:如果只有一个构造函数,@Autowired注解可以省略。(通常来说,也只有一个构造函数)

3). setter注入

/**
 * 用户信息Controller
 */
@RestController
public class UserController {
    
    //方式三: setter注入
    private UserService userService;
    
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    
}    
  • 优点:保持了类的封装性,依赖关系更清晰。

  • 缺点:需要额外编写setter方法,增加了代码量。

小结:在项目开发中,基于@Autowired进行依赖注入时,基本都是第一种和第二种方式。(官方推荐第二种方式,因为会更加规范)但是在企业项目开发中,很多的项目中,也会选择第一种方式因为更加简洁、高效(在规范性方面进行了妥协)。 

注意事项

那如果在IOC容器中,存在多个相同类型的bean对象,会出现什么情况呢?

在下面的例子中,我们准备了两个UserService的实现类,并且都交给了IOC容器管理。 代码如下:

此时,我们启动项目会发现,控制台报错了:

 出现错误的原因呢,是因为在Spring的容器中,UserService这个类型的bean存在两个,框架不知道具体要注入哪个bean使用,所以就报错了。

如何解决上述问题呢?Spring提供了以下几种解决方案:

  • @Primary

  • @Qualifier

  • @Resource

方案一:使用@Primary注解

当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认的实现。

@Primary
@Service 
public class UserServiceImpl implements UserService {
 }

方案二:使用@Qualifier注解

指定当前要注入的bean对象。 在@Qualifier的value属性中,指定注入的bean的名称。 @Qualifier注解不能单独使用,必须配合@Autowired使用。

@RestController
public class UserController {

    @Qualifier("userServiceImpl")
    @Autowired
    private UserService userService;

方案三:使用@Resource注解

是按照bean的名称进行注入。通过name属性指定要注入的bean的名称。

@RestController
public class UserController {
        
    @Resource(name = "userServiceImpl")
    private UserService userService;

 

 总结一下:

方案一是直接在类上指明优先级,告诉spring如果出现多个同种类型的bean优先选择哪一个。

方案二三是在为类注入bean的时候具体指明我要注入哪个bean,只不过@Autowired 默认是按照类型注入,而@Resource是按照名称注入

个人理解:

方案二和方案三的解决方法都不上很好,因为之所以使用依赖注入就是为了解决模块之间的耦合问题,实现二三两种方法其实不同模块之间还是会出现耦合的情况。个人感觉方案一会更好。

面试题:@Autowird 与 @Resource的区别

  • @Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解

  • @Autowired 默认是按照类型注入,而@Resource是按照名称注入

小结:

1. 依赖注入的注解 @Autowired :默认按照类型自动装配 如果同类型的 bean 存在多个: • @Primary • @Autowired + @Qualifier • @Resource 2. @Resource 与 @Autowired 区别 ? @Autowired 是 Spring 框架提供的注解,而 @Resource 是 JavaEE 规范提供的 @Autowired 默认是按照类型注入,而 @Resource 默认是按照名称注入

标签:Web,Dl,Resource,Autowired,bean,注解,IOC,注入
From: https://blog.csdn.net/m0_63949203/article/details/145106323

相关文章

  • 你了解什么是无障碍web(WAI)吗?在开发过程中要怎么做呢?
    无障碍Web(WebAccessibilityInitiative,简称WAI)是由万维网联盟(WorldWideWebConsortium,简称W3C)发起的一个国际性计划,旨在提高网络内容和服务对所有用户的无障碍性,包括残疾人士。该计划制定了一系列指导原则和推荐实践,帮助网站开发者、设计者和内容创作者确保他们的产品对所有人......
  • 基于FFmpeg 6.x与SDL2的音视频播放器开发全解析
    多媒体播放器系列基于FFmpeg6.x与SDL2的音视频播放器开发全解析多媒体播放器系列基于FFmpeg6.x与SDL2的音视频播放器开发全解析一、引言二、FFmpeg6.x基础理论(一)FFmpeg概述(二)重要的数据结构(三)音视频解码流程三、SDL2基础理论(一)SDL2概述(二)重要的模......
  • 应急响应-web3
    应急响应-知攻善防web3前景需要:小苕在省护值守中,在灵机一动情况下把设备停掉了,甲方问:为什么要停设备?小苕说:我第六感告诉我,这机器可能被黑了。这是他的服务器,请你找出以下内容作为通关条件:Windows:administrator/xj@1234561.请输入攻击者第一个ip地址192.168.75.129192......
  • Linux电源管理——Suspend-to-Idle(s2idle) 流程
    目录一、常见的Suspend方式1、Suspend-to-idle2、Standby 3、Suspend-to-RAM4、Hibernation 二、代码分析1、state_store2、suspend_enter3、s2idle_loop4、idleloop5、psci_enter_idle_state6、cpu_suspend7、开始resume流程8、开启IRQ中断9、pm_syst......
  • 实现无感刷新Token技术:.Net Web API与axios的完美结合
    备忘:https://mp.weixin.qq.com/s?__biz=MjM5MDE5MDM5NA==&mid=2449944319&idx=1&sn=71e84d8ee24769e77b19ca8367333b8f&chksm=b1bb10aa86cc99bc2f20686354e8184023278de74dba857a42d720dc47fabb654c12ecb83524&scene=21#wechat_redirect我们都知道Token是有设置有效期......
  • webman: start.php的应用
    一,查看帮助:$phpstart.phphelpUsage:phpyourfile<command>[mode]Commands:startStartworkerinDEBUGmode.Usemode-dtostartinDAEMONmode.stopStopworker.Usemode-gtostopgracefully.......
  • Web前端------HTML块级和行内标签之行内标签
    一.行内标签介绍 行内标签----span      作用:        1.作为文本字体的容器,用来结合CSS修饰文本样式        2.根据行内标签的特性(不换行/部分块级样式不生效eg:宽高等等),做微小布局二.代码展示<!DOCTYPEhtml><htmllang=......
  • webview是什么,和小程序的关系
    文章目录什么是WebView?WebView的核心特点WebView和小程序的关系1.**WebView是小程序的重要组件**2.**小程序中的WebView功能**3.**小程序中的`<web-view>`组件**WebView在小程序中的作用和架构小程序的运行架构页面切换与多WebViewWebView在小程序中的优......
  • 47. web框架
    1.web框架本质web框架本质上可以看成一个功能强大的socket服务端,用户的浏览器可以看成拥有可视化界面的socket客户端通过网络请求实现数据交互,可简单的将web框架看做是对前端、数据库的全方位整合2.手写简易版web框架服务端importsocketserver=socket.socket()serv......
  • java基于WEB的高校实训管理系统论文+源码 2025毕设
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着信息技术的飞速发展,高校教育也在不断地变革与创新。在高校的教学体系中,实训教学作为培养学生实践能力和综合素质的关键环节,其管理的高效性和......