簡體   English   中英

Spring的@Bean注解和@Component注解有什么區別?

[英]what is the difference between @Bean annotation and @Component annotation at Spring?

這對你來說可能是一個非常簡單的問題。但我讀了很多文檔,我完全糊塗了。我們可以使用 @Component 代替 @Bean 或 @Bean 代替 @Component(以及 @Repository @Service @Controller) 嗎?

干杯

成分

@Component也用於@Service@Repository用於使用類路徑掃描自動檢測和自動配置bean。

只要這些類在我們的基礎包下或者 Spring 知道另一個要掃描的包,就會為這些類中的每一個創建一個新的 bean

Bean 和組件被映射為一對一,即每個類一個 bean。

這些注釋( @Component, @Service, @Repository )是類級別的注釋。

例子:

假設我們有一個 UserService 類,其中包含用戶操作的所有方法。

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public User findByUsername( String username ) throws UsernameNotFoundException {
        User u = userRepository.findByUsername( username );
        return u;
    }

    public List<User> findAll() throws AccessDeniedException {
        List<User> result = userRepository.findAll();
        return result;
    }
}

Spring 將為 UserService 創建一個 Bean,我們可以在多個位置/類中使用它。

@豆角,扁豆

@Bean用於聲明單個 bean,而不是像 Component 那樣讓 Spring 自動執行。

它將 bean 的聲明與類定義分離,並允許您按照自己的選擇創建和配置 bean。

@Bean 用於方法級別,可以根據需要進行配置

例如:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    
    @Bean
    public SpringTemplateEngine springTemplateEngine()
    {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.addTemplateResolver(htmlTemplateResolver());
        return templateEngine;
    }

       @Bean
    public SpringResourceTemplateResolver htmlTemplateResolver()
    {
        SpringResourceTemplateResolver emailTemplateResolver = new SpringResourceTemplateResolver();
        emailTemplateResolver.setPrefix("classpath:/static/template/");
        emailTemplateResolver.setSuffix(".html");
        emailTemplateResolver.setTemplateMode("HTML");
        emailTemplateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
        return emailTemplateResolver;
    }


...

在此處閱讀有關定型注釋的更多信息。

@Bean用於將方法定義為生產者,它告訴Spring使用該方法來檢索方法返回類型的對象,並在需要時將該對象作為依賴項注入。

@Component用於定義一個類作為Spring組件,它告訴Spring創建一個對象(如果它是 Singleton)並處理它的生命周期和依賴項,並在需要時注入該對象。

@Service@Repository基本上就像 @Component 和 AFAIK 它們只是為了更好地對組件進行分組。

@Service用於定義具有業務邏輯的服務類, @Repository用於定義與數據庫等底層系統交互的存儲庫類。

@成分

如果我們用@Component 或其他 Stereotype 注釋之一標記一個類,這些類將使用類路徑掃描自動檢測。 只要這些類在我們的基礎包下或者 Spring 知道另一個要掃描的包,就會為每個類創建一個新的 bean。

package com.beanvscomponent.controller;

import org.springframework.stereotype.Controller;

@Controller
public class HomeController {

    public String home(){
       return "Hello, World!";
   }

 }

在帶注釋的類和 bean 之間存在隱式的一對一映射(即每個類一個 bean)。 這種方法對接線的控制非常有限,因為它純粹是聲明性的。 同樣重要的是要注意構造型注釋是類級別的注釋。

@豆角,扁豆

@Bean 用於顯式聲明單個 bean,而不是像我們對 @Controller 那樣讓 Spring 自動執行。 它將 bean 的聲明與類定義分離,並允許您按照自己的選擇創建和配置 bean。 使用@Bean,您不會將此注釋置於類級別。 如果您嘗試這樣做,您將收到無效類型錯誤。 @Bean 文檔將其定義為:

Indicates that a method produces a bean to be managed by the Spring container.

通常,@Bean 方法是在 @Configuration 類中聲明的。我們有一個用戶類,我們需要實例化它,然后使用該實例創建一個 bean。 這就是我之前所說的,我們對 bean 的定義方式有更多的控制。

package com.beanvscomponent;

public class User {

private String first;
private String last;

public User(String first, String last) {
    this.first = first;
    this.last = last;
   }
}

正如我之前提到的,@Bean 方法應該在 @Configuration 類中聲明。

package com.beanvscomponent;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ApplicationConfig {

@Bean
public User superUser() {
    return new User("Partho","Bappy");
   }

}

方法的名稱實際上將是我們 bean 的名稱。 如果我們拉起執行器中的 /beans 端點,我們可以看到定義的 bean。

{
"beans": "superUser",
"aliases": [],
"scope": "singleton",
"type": "com.beanvscomponent.User",
"resource": "class path resource 
    [com/beanvscomponent/ApplicationConfig.class]",
"dependencies": []
}

@Component vs @Bean

在此處輸入圖片說明

我希望澄清一些關於何時使用 @Component 和何時使用 @Bean 的事情。 這可能有點令人困惑,但是當您開始編寫更多應用程序時,它會變得非常自然。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM