成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

太強了!Spring Boot 中 12 種獲取 Bean 的神操作,最后一種你想不到

開發 前端
在本篇文章中我們將介紹 12 種 獲取 Bean 方式,能幫助我們更高效、更優雅地應對各種開發挑戰。它們能讓我們在面對不同業務場景時,迅速找到最適合的 Bean 獲取策略,從而提升開發效率,優化代碼結構,讓 Spring Boot 應用程序更加健壯和靈活。

環境:SpringBoot3.4.2

1. 簡介

在 Spring Boot 日常開發中,獲取 Bean 是極為頻繁且關鍵的操作。無論是處理業務邏輯的服務層,還是負責數據交互的持久層,亦或是控制請求響應的控制器層,都離不開對 Bean 的調用。

然而,面對復雜多變的業務需求和架構設計,單一的 Bean 獲取方式往往難以滿足開發者的需求。有時我們需要根據特定的條件、場景或設計模式來靈活獲取 Bean。此時,掌握多種獲取 Bean 的方法就顯得尤為重要。

在本篇文章中我們將介紹 12 種 獲取 Bean 方式,能幫助我們更高效、更優雅地應對各種開發挑戰。它們能讓我們在面對不同業務場景時,迅速找到最適合的 Bean 獲取策略,從而提升開發效率,優化代碼結構,讓 Spring Boot 應用程序更加健壯和靈活。

2.實戰案例

準備如下類:

@Service
@Qualifier("us")
public class UserService {
  public Object query() {
    return "User" ;
  }
}

在接下來的示例中我們將通過12種方式來獲取上面定義的UserService bean對象。

2.1 使用@Autowired

@Component
@Order(1)
public class ObatinBeanRunner1 implements CommandLineRunner {
  @Autowired
  private UserService userService ;
  @Override
  public void run(String... args) throws Exception {
    System.err.println("方法1: 【@Autowired】 - " + this.userService.query()) ;
  }
}

最常用的方式,適用于 Spring 管理的組件(如 Controller、Service 等)。

注意:官方已不推薦通過字段注入的方式了。如下官方說明:

圖片圖片

2.2 使用@Resource

@Component
@Order(2)
public class ObatinBeanRunner2 implements CommandLineRunner {
  @Resource
  private UserService userService ;
  @Override
  public void run(String... args) throws Exception {
    System.out.println("方法2: 【@Resource】 - " + this.userService.query()) ;
  }
}

需要按名稱注入 Bean(JDK 自帶注解),可以通過指定name屬性來設置按照名稱注入。

2.3 使用@Inject

@Component
@Order(3)
public class ObatinBeanRunner3 implements CommandLineRunner {
  @Inject
  private UserService userService ;
  @Override
  public void run(String... args) throws Exception {
    System.err.println("方法3: 【@Inject】 - " + this.userService.query()) ;
  }
}

使用該注解,需要引入如下依賴:

<dependency>
  <groupId>jakarta.inject</groupId>
  <artifactId>jakarta.inject-api</artifactId>
</dependency>

@Inject注解是JSR-330標準注解,同時該注解還可以與@Named一起使用來限定注入的bean。

2.4 構造函數注入

@Component
@Order(4)
public class ObatinBeanRunner4 implements CommandLineRunner {
  private final UserService userService ;
  public ObatinBeanRunner4(UserService userService) {
    this.userService = userService ;
  }
  @Override
  public void run(String... args) throws Exception {
    System.out.println("方法4: 【構造函數注入(官方推薦)】 - " + this.userService.query()) ;
  }
}

Spring 官方推薦的方式,保證依賴不可變,避免空指針異常。

2.5 使用ApplicationContext

@Component
@Order(5)
public class ObatinBeanRunner5 implements CommandLineRunner, ApplicationContextAware {
  private ApplicationContext context ;
  @Override
  public void run(String... args) throws Exception {
    UserService userService = this.context.getBean(UserService.class) ;
    System.err.println("方法5: 【通過ApplicationContext#getBean方法】 - " + userService.query()) ;
  }
  @Override
  public void setApplicationContext(ApplicationContext context) throws BeansException {
    this.context = context ;
  }
}

需要運行時動態獲取 Bean(如工具類、工廠模式)。

2.6 使用BeanFactory

@Component
@Order(6)
public class ObatinBeanRunner6 implements CommandLineRunner, BeanFactoryAware {
  private BeanFactory beanFactory ;
  @Override
  public void run(String... args) throws Exception {
    UserService userService = this.beanFactory.getBean(UserService.class) ;
    System.out.println("方法6: 【通過BeanFactory#getBean方法】 - " + userService.query()) ;
  }
  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    this.beanFactory = beanFactory ;
  }
}

相比ApplicationContext更加輕量,功能也要少。

2.7 使用ObjectProvider

@Component
@Order(7)
public class ObatinBeanRunner7 implements CommandLineRunner {
  private final ObjectProvider<UserService> userServiceProvider ;
  public ObatinBeanRunner7(ObjectProvider<UserService> userServiceProvider) {
    this.userServiceProvider = userServiceProvider;
  }
  @Override
  public void run(String... args) throws Exception {
    UserService userService = this.userServiceProvider.getIfUnique() ;
    if (userService != null) {
      System.err.println("方法7: 【ObjectProvider】 - " + userService.query()) ;
    }
  }
}

解決循環依賴或可選依賴(Bean 可能不存在),安全獲取bean,并且還支持流式操作。我們不僅可以使用 ObjectProvider 還可以使用 ObjectFactory 或Optional。

2.8 使用@Lookup

@Component
@Order(8)
public abstract class ObatinBeanRunner8 implements CommandLineRunner {
  @Lookup
  public abstract UserService getUserService() ;
  @Override
  public void run(String... args) throws Exception {
    UserService userService = this.getUserService() ;
    System.out.println("方法8: 【@Lookup】 - " + userService.query()) ;
  }
}

每次調用都需要新的原型(Prototype)Bean 實例。通常可以通過該注解解決單例bean依賴原型bean的情況。

2.9 使用BeanFactoryUtils

@Component
@Order(9)
public class ObatinBeanRunner9 implements CommandLineRunner, BeanFactoryAware {
  private ListableBeanFactory beanFactory ;
  @Override
  public void run(String... args) throws Exception {
    UserService userService = BeanFactoryUtils.beanOfType(this.beanFactory, UserService.class) ;
    System.err.println("方法9: 【BeanFactoryUtils】 - " + userService.query()) ;
  }
  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    if (beanFactory instanceof ListableBeanFactory bf) {
      this.beanFactory = bf ;
    }
  }
}

該類是Spring自帶的工具類,其還是依賴BeanFactory。

2.10 使用BeanFactoryAnnotationUtils

@Component
@Order(10)
public class ObatinBeanRunner10 implements CommandLineRunner, BeanFactoryAware {
  private ListableBeanFactory beanFactory ;
  @Override
  public void run(String... args) throws Exception {
    UserService userService = BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, UserService.class, "us") ;
    System.out.println("方法10: 【BeanFactoryAnnotationUtils】 - " + userService.query()) ;
  }
  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    if (beanFactory instanceof ListableBeanFactory bf) {
      this.beanFactory = bf ;
    }
  }
}

該工具類,我們可以用來獲取那些使用了@Qualifier注解的具體bean對象。

2.11 自定義工具類

@Component
public class SpringUtils implements ApplicationContextAware {
  private static ApplicationContext context;
  @Override
  public void setApplicationContext(ApplicationContext context) {
    SpringUtils.context = context;
  }
  public static <T> T getBean(Class<T> beanClass) {
    return context.getBean(beanClass);
  }
}

通過定義靜態方法,這樣我們可以在Spring容器完全啟動完成或,在任意類中使用了。

@Component
@Order(11)
public class ObatinBeanRunner11 implements CommandLineRunner {


  @Override
  public void run(String... args) throws Exception {
    UserService userService = SpringUtils.getBean(UserService.class) ;
    System.err.println("方法11: 【靜態方法】 - " + userService.query()) ;
  }
}

2.12 使用@Value+SpEL

@Component
@Order(12)
public class ObatinBeanRunner12 implements CommandLineRunner {


  @Value("#{@userService}")
  private UserService userService ;


  @Override
  public void run(String... args) throws Exception {
    System.err.println("方法12: 【@Value + SpEL】 - " + userService.query()) ;
  }
}

通過SpEL表達式來引用其它的bean,內部會自動的進行類型的轉換。注意:這里的userService是對應的bean名稱。

以上12種方法最終輸出結果如下:

圖片圖片

責任編輯:武曉燕 來源: Springboot全家桶實戰案例
相關推薦

2025-01-13 13:47:13

2025-06-09 01:22:00

2023-12-13 14:26:29

2012-07-11 10:38:34

JavaScript

2022-08-18 09:38:02

Spring跨域

2023-01-13 07:41:20

BeanSpring容器

2024-01-02 07:56:13

ReactuseEffect數據驅動 UI

2009-04-18 06:23:33

Linux漫畫

2020-12-09 10:15:34

Pythonweb代碼

2025-05-14 01:00:00

Spring工具工廠類

2021-07-05 18:05:40

SpringBean方法

2020-12-23 10:10:23

Pythonweb代碼

2022-07-07 10:33:27

Python姿勢代碼

2022-06-22 09:44:41

Python文件代碼

2025-04-02 04:55:00

2025-01-22 14:02:35

2023-10-17 08:55:08

數據庫數據業務

2025-02-10 08:43:31

Java異步編程

2024-10-22 15:51:42

PyTorch張量

2019-07-01 14:39:44

Jupyter擴展Python
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩欧美在线观看视频 | 黄色毛片一级 | 国产一区二区不卡 | 精品国产一区二区三区日日嗨 | 精品中文字幕在线 | 国产一区| 国产成人高清视频 | 国产亚洲一区二区在线观看 | 亚卅毛片| 91精品国产91久久综合桃花 | 亚洲97 | 雨宫琴音一区二区在线 | 狠狠干av | 精品国产精品三级精品av网址 | 日日夜夜天天久久 | 亚洲精品久久久久中文字幕二区 | 国产日韩一区二区三区 | 国产亚洲精品综合一区 | 国产日韩一区 | 免费在线观看成人av | 亚洲精品在线免费观看视频 | 国产精品成人一区二区三区 | 麻豆精品久久久 | av中文网 | 福利久久 | 国产一区二区视频在线观看 | 中文字幕亚洲国产 | 精品欧美一区二区三区免费观看 | 欧美成人精品一区二区男人看 | 午夜视频一区 | 亚洲精品一区在线观看 | 欧洲毛片 | 一区二区三区福利视频 | 亚洲视频在线看 | 免费看国产片在线观看 | 天天拍天天射 | 日韩三级在线观看 | 99资源 | 亚洲天堂男人的天堂 | 亚洲日韩中文字幕一区 | 毛片大全|