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


    让我告诉你什么叫水货。

    一、水货横行

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

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

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

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

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

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

    @Component
    @Order(2)
    public class Demo1 implements ApplicationRunner {
        @Override
        public void run(ApplicationArguments args) throws Exception {
    		System.out.println("我像一只鱼儿在你的荷塘");
        }
        
        @PreDestroy
        public void exit() {
            System.out.println("demo exit");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

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

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

    public interface MyService {
        void doSomething();
    }
    
    @Service
    public class ServiceOne implements MyService {
        @Override
        public void doSomething() {
            System.out.println("领导动动");
        }
    }
    
    @Controller
    public class MyController {
        @Autowired
        private MyService myService;
    
        public void performAction() {
            myService.doSomething();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    结果领导一动不动,像死了一样,除非触发了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

    1)@Autowired

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

        @Autowired
        private MyService myService;
    
    • 1
    • 2

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

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

    2)@Resource和@Autowired

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

    @Resource:

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    @Autowired:

    public interface MyService {
        void doSomething();
    }
    
    @Service("serviceOne")
    public class ServiceOne implements MyService {
        @Override
        public void doSomething() {
            System.out.println("Service One is doing something");
        }
    }
    
    @Service("serviceTwo")
    public class ServiceTwo implements MyService {
        @Override
        public 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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    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;
            }
    		
    		。。。
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在这里插入图片描述

    四、我的java技能

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

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

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

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

  • 相关阅读:
    淘宝API详情接口调用示例
    2022 AI趋势8大预测
    6个专业剪辑必备的音效素材网站
    golang程序能不能用LD_PRELOAD进行hook?
    git 常用命令总结
    巧用大数据分析工具,让本地数据输入速度提升2倍的方法
    【云开发】给我 10 分钟,带你上手一个 AWS serverless web server
    pnpm install报错 Value of “this“ must be of type URLSearchParams
    MATLAB环境下基于深度学习的语音降噪方法
    C# String类的方法
  • 原文地址:https://blog.csdn.net/leftfist/article/details/137928905