spring boot中的标注@Component、@Service等

embedded/2024/10/18 14:21:03/

让我告诉你什么叫水货。

一、水货横行

一直以来,我对Spring Boot项目中的标注,像@Component啦、@Service啦、@Configuration啦,甚至@Autowired啦,等等,都似懂非懂。@Autowired与@Resource有什么区别也不清楚。

个中原因,一是本人资质愚钝,二是懒,所谓读书不求甚解,程序能编译、运行就可以,都是从网上、别人处抄过来的,为什么要加这些注解,不明觉厉,提不起兴趣做深入的了解。之前虽然也有搜寻过,但没有理解,只是简单地做个记录就完事。(springboot中依赖对象实例化问题)

所以说,虽然java用了好几年,其实并不怎么懂,是个水货,每次说自己是一个java程序员都不禁一阵心虚。

ComponentService_8">二、再认识一遍@Component、@Service等标注

为什么现在又查了一遍资料,学习一下这些标注,比较一下它们的异同呢?

原因是我发现,类头带上标注@Component,好像就会自动执行:

java">@Component
@Order(2)
public class Demo1 implements ApplicationRunner {@Overridepublic void run(ApplicationArguments args) throws Exception {System.out.println("我像一只鱼儿在你的荷塘");}@PreDestroypublic void exit() {System.out.println("demo exit");}
}

结果系统一启动,它就输出了:我像一只鱼儿在你的荷塘。好神奇哟!

难道@Component有这种魔力,可以让一个类自动运行?你看@Service就不会,我们写的服务实现类,都在头部加上@Service,但它不会自动执行,只能在别的什么地方通过@Autowired显式声明,然后调用才能运行。不主动调用就一动不动:

java">public interface MyService {void doSomething();
}@Service
public class ServiceOne implements MyService {@Overridepublic void doSomething() {System.out.println("领导动动");}
}@Controller
public class MyController {@Autowiredprivate MyService myService;public void performAction() {myService.doSomething();}
}

结果领导一动不动,像死了一样,除非触发了performAction()这个方法。

果真如此吗?

三、真相

1、真相1

事实并非如此。

@Component ,@Service , @Repository , @Controller , @Configration这些标注,放在类头,作用是使得Spring能够扫描到它们,在程序启动之初,就自动把它们实例化,将其注册为bean,放到spring容器中,从而可以被其他组件引用和使用。

其中,@Component ,@Service , @Repository,并不会自动运行;而@Configration会自动运行。在Spring框架中,当一个类被标记为@Configuration时,Spring除了会在应用启动时自动实例化这个类,还会运行其中的方法,用于创建和配置bean。这些bean定义方法通常使用@Bean注解来声明。

@Controller也算会自动运行。Spring会在应用启动时实例化带该标注的类,并将其注册为一个控制器,以便等待客户端的请求。

我前面的例子,@Component标注的类之所以会自动运行,可能是因为它实现了ApplicationRunner的缘故。

而@Service似乎是@Component的子类,跟@Component类似。

2、真相2

Autowired_75">1)@Autowired

我一直以为,@Autowired的作用是实例化一个对象,你看下面,难道不是自动创建一个MyService实例吗?

java">    @Autowiredprivate MyService myService;

并不准确!@Autowired注解的作用是实现依赖注入。何谓依赖注入?就是一个对象里面,使用另一个对象。通常,我们手动写代码应用依赖注入,是将别的对象实例在构造函数或别的方法中作为参数传入。而有了@Autowired,就像普通属性一样声明,只要加上这个注解就可以了。简化了代码。依赖注入和实例化对象是不同的两个概念。当然啦,依赖注入时,用到的实例,应该就是Spring容器中实例化了的Bean。

上面代码的意思应该是,从容器中捞出实现了MyService的Bean,赋给变量myService;而不是系统临时自动new一个MyService实例,然后赋给myService,因为这个实例,早在系统启动的时候就已经new了,并且注册成bean放在了容器里。

Autowired_88">2)@Resource和@Autowired

@Resource和@Autowired作用一样。二者的区别,一是@Resource来自于JEE,也可以用于Spring Boot;而@Autowired只能用于Spring Boot;二是@Resource可以通过name属性清晰地指向某个Bean,@Autowired可能要结合@Qualifier才可以。

@Resource:

java">public interface UserRepository {User findUserById(Long id);
}@Service("userRepositoryImpl")
public class UserRepositoryImpl implements UserRepository {// 实现...
}@Service
public class UserService {// 使用@Resource按名称装配,"userRepositoryImpl"对应于上面定义的Bean的名称@Resource(name = "userRepositoryImpl")private UserRepository userRepository;public User getUserById(Long id) {return userRepository.findUserById(id);}
}

@Autowired:

java">public interface MyService {void doSomething();
}@Service("serviceOne")
public class ServiceOne implements MyService {@Overridepublic void doSomething() {System.out.println("Service One is doing something");}
}@Service("serviceTwo")
public class ServiceTwo implements MyService {@Overridepublic void doSomething() {System.out.println("Service Two is doing something");}
}@Controller
public class MyController {// 默认按类型自动装配,由于有多个MyService的实现类,所以需要加上@Qualifier来明确指定@Autowired@Qualifier("serviceOne") // 按照@Bean的名称进行装配private MyService myService;public void performAction() {myService.doSomething();}
}

3)Autowried的优点

就是降低复杂性。试想,手动依赖注入,每个类的构造函数都塞满了参数,你中有我,我中有你。看看之前C#的代码:

    public class CxService:ICxService{P.ICxService pService;R.ICxService rService;ICache cache;ICheck_Cx_MasterRepository check_Cx_MasterRepository;ICheck_Cx_DetailRepository detailRepository;IWordExportService exportService;public CxService(ICache cache,P.ICxService pService,R.ICxService rService,ICheck_Cx_MasterRepository masterRepository,ICheck_Cx_DetailRepository detailRepository,IWordExportService exportService){this.cache = cache;this.pService = pService;this.rService = rService;this.check_Cx_MasterRepository = masterRepository;this.detailRepository = detailRepository;this.exportService = exportService;}。。。
}

在这里插入图片描述

java_187">四、我的java技能

虽然我用java从2018年开始,到现在有6年了,但事实上一直用的都是Spring Boot。并且对Spring Boot也不熟悉,只会一些简单的应用,增删改查而已。

来,让我们重温一下,Spring Boot这一Java开发框架,其核心有三:
1)IoC容器,顾名思义是控制反转容器?又名Spring容器?作用就是将类自动实例化,注册成Bean,放到Ioc容器里。IoC的好处是省事,也许还节省资源;

2)上下文
建造者模式。看上去,@Autowired应该属于上下文的范畴。

3)Spring核心
工具类
在这里插入图片描述


http://www.ppmy.cn/embedded/15653.html

相关文章

CJSON工具类

4.4.3.CJSON工具类 OpenResty提供了一个cjson的模块用来处理JSON的序列化和反序列化。 官方地址: https://github.com/openresty/lua-cjson/ 1)引入cjson模块: local cjson require "cjson"2)序列化: …

定制自己的 AI 角色CustomChar;AI知识点和面试题;提高llama 3 的微调速度Unsloth

✨ 1: CustomChar 允许你创建和定制自己的 AI 角色 CustomChar 是一个开源项目,它允许你创建和定制自己的 AI 角色。无论是游戏中的角色,还是个人的虚拟助手(比如电脑上的 JARVIS),甚至是在线教育体验中的虚拟朋友或…

前端发送请求,显示超时取消

前端发送请求,显示超时取消 问题说明:后台接口请求60s尚未完成,前端控制台显示取消(canceled) 原因 1、前端设置60s超时则取消 2、后台接口响应时间过长,过长的原因统计的数据量多(实际也才17…

短视频评论ID批量爬虫提取获客软件|视频评论下载采集工具

短视频评论批量抓取软件:智能拓客,精准抓取用户反馈 主要功能一览 1. 智能抓取任务创建: 软件提供了任务创建功能,用户只需输入任务名称、搜索关键词以及评论监控词,即可开始智能抓取。不仅能够搜索关键词匹配的视频…

Python基础:【习题系列】面向对象

在Python中,用于定义类的关键字是什么?( B ) A.classs B.class C.Class D.type 答案:B 难易程度:易 答案解析:在Python中,定义类需要使用关键字class。 知识点:类定义;Python关键字 在Python中,以下哪个关键字用于在类中引用同一类的其他方法或属性?( C ) A.…

深入解析CSS3 @font-face 规则:自定义与网络字体全面指南

CSS3的font-face规则为网页设计开辟了全新的天地,允许开发者引入自定义字体以及网络字体资源,极大丰富了网页的视觉表现力与品牌一致性。本文不仅将详细解析font-face规则的工作原理、关键属性,还将指导您如何在实际项目中应用自定义字体&…

项目上线流程(保姆级教学)

01:注册阿里云账户 02:登录阿里云 03:在桌面新建记事本保存个人账号密码等信息 04:完成重置密码 05:安装宝塔面板 命令行 yum install -y wget && wget -O install.sh http://download.bt.cn/install/instal…

深入刨析 mysql 底层索引结构B+树

文章目录 前言一、什么是索引?二、不同索引结构对比2.1 二叉树2.2 平衡二叉树2.3 B-树2.4 B树 三、mysql 的索引3.1 聚簇索引3.2 非聚簇索引 前言 很多人看过mysql索引的介绍:hash表、B-树、B树、聚簇索引、主键索引、唯一索引、辅助索引、二级索引、联…