首页
学习
活动
专区
圈层
工具
发布

腾讯二面:@Bean 与 @Component 用在同一个类上,会怎么样?

这个问题一听上去好像挺刁钻的,其实逻辑很简单,但很多人因为日常没注意,就容易掉坑里。我就拿个小 demo 来说明。

先说两个注解的作用

@Component:直接标在类上,Spring 做包扫描的时候会把这个类注册成 bean。

@Bean:一般写在方法上,方法的返回值会注册成 bean,方法名就是 bean 的名字,除非你自己指定。

所以一个是类级别的,一个是方法级别的,功能上其实没冲突。

demo 示例

我写了个最简单的例子:

import org.springframework.context.annotation.Bean;

import org.springframework.stereotype.Component;

@Component

publicclass MyService {

  public String hello() {

      return"hello from component";

  }

  @Bean

  public Helper helper() {

      returnnew Helper();

  }

  publicstaticclass Helper {

      public String help() {

          return"i am helper";

      }

  }

}

然后我写个启动类:

import org.springframework.boot.CommandLineRunner;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ApplicationContext;

@SpringBootApplication

publicclass DemoApplication implements CommandLineRunner {

  privatefinal ApplicationContext context;

  public DemoApplication(ApplicationContext context) {

      this.context = context;

  }

  public static void main(String[] args) {

      SpringApplication.run(DemoApplication.class, args);

  }

  @Override

  public void run(String... args) {

      MyService myService = context.getBean(MyService.class);

      System.out.println(myService.hello());

      MyService.Helper helper = context.getBean(MyService.Helper.class);

      System.out.println(helper.help());

  }

}

启动日志和输出

项目跑起来的时候,你会在日志里看到 Spring 注册了两个 bean,一个叫myService,另一个叫helper。运行输出是这样的:

hello from component

i am helper

很直观吧? 所以这就说明@Component和@Bean同时用的时候,Spring 会把类本身注册成一个 bean,再把方法返回的对象也注册进去,互不干扰。

但这里有个坑

如果这个类不是@Configuration而是@Component,那么它里面的@Bean方法不会被 Spring 用代理增强。什么意思呢?就是如果你在同一个类里写两个@Bean方法,方法 A 里去调用方法 B,那返回的可能是新建的实例,而不是单例。这个细节很多人忽略了。

所以虽然同时用不会报错,但实际开发中最好还是分开用:

工厂方法写在@Configuration类里,配合@Bean。

普通业务类就直接用@Component。

这样不容易踩坑,也方便别人看懂。

  • 发表于:
  • 原文链接https://page.om.qq.com/page/OHtDY_zvajXHFNYV8C0o-uXg0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。
领券