Bahar: @Bileşen ve @Bean


459

@ComponentSınıf yolu taraması kullanarak xml fasulye tanımından kurtulmak için ek açıklama 2.5 baharında tanıtıldığını anlıyorum .

@Bean3.0 baharında tanıtıldı ve @Configurationtamamen xml dosyasından kurtulmak ve bunun yerine java config kullanmak için kullanılabilir.

@ComponentEk açıklama eklemek yerine ek açıklamayı yeniden kullanmak mümkün olabilir @Beanmiydi? Anladığım kadarıyla, nihai hedef her iki durumda da fasulye yaratmak.


4
@Bean'ın Configuration sınıfının dışında kullanılabileceği herhangi bir yer var mı?
Willa


@Willa Evet, var. Buna denir Lite mode. Ve tavsiye edilmez. Buraya bakın: docs.spring.io/spring/docs/current/spring-framework-reference/…
smwikipedia

9
Daha sonra gerektiğinde bahar IoC motoru tarafından örneklendirilebilen bir sınıfı tanımlarken, bir @beanfasulyenin özelleştirilebilir bir örneğini döndüren bir yöntem olduğunu söyleyerek özetleyeceğim @component.
Sebas

Yanıtlar:


433

@Componentve @Beanbirbirinden oldukça farklı iki şey yapın ve karıştırılmamalıdır.

@Component(ve @Serviceve @Repository) sınıf yolu taraması kullanarak çekirdekleri otomatik olarak algılamak ve otomatik olarak yapılandırmak için kullanılır. Açıklamalı sınıf ile fasulye (ör. Sınıf başına bir fasulye) arasında örtük bire bir eşleme vardır. Kablolama kontrolü bu yaklaşımla oldukça sınırlıdır, çünkü tamamen beyan edicidir.

@BeanSpring'in yukarıdaki gibi otomatik olarak yapmasına izin vermek yerine açıkça tek bir fasulyeyi beyan etmek için kullanılır . Fasulye deklarasyonunu sınıf tanımından ayırır ve fasulyeleri tam olarak nasıl seçtiğinizi oluşturmanıza ve yapılandırmanıza izin verir.

Soruna cevap vermek için...

@Componentek açıklama eklemek yerine ek açıklamayı yeniden kullanmak mümkün olabilir @Beanmiydi?

Elbette, muhtemelen; ama seçmediler, çünkü ikisi oldukça farklı. Bahar, suları daha fazla çamurlamadan yeterince kafa karıştırıyor.


3
Sadece otomatik @Componentkablolu gerektiğinde kullanabilir miyim ? Öyle görünüyor @Beanetkileyemez@Autowired
Jaskey

3
servis tabanlı sınıflar için '@ bileşen' kullanın, fabrikada daha fazla özel yapım nesne olarak '@Bean' kullanın, örn. jdbc datasource
Junchen Liu

2
Kullanabileceğiniz @Jaskey @Autowiredile @Beansizinle Fasulye sınıf açıklamalı varsa@Configuration
starcorn

6
Üzgünüm ama açıklamanızla ilgili bir kelime anlayamıyorum. Bunu açıkça anlıyorsunuz, lütfen açık bir açıklama yazar mısınız veya uygun belgelere işaret eder misiniz?
Alex Worden

13
Şimdi (diğer insanların cevaplarını okuyarak) kavramı anladığım için açıklamanız mantıklı. Bu da bana, açıklamanızın kavramları zaten anlamayan kimseye bir faydası olmadığını söyler.
Alex Worden

397

@ Bileşen Bileşen taraması ve otomatik kablolama için tercih edilir.

@Bean'ı ne zaman kullanmalısınız ?

Bazen otomatik yapılandırma bir seçenek olmayabilir. Ne zaman? Bileşenleri üçüncü taraf kitaplıklardan bağlamak istediğinizi düşünelim (kaynak kodunuz yok, bu yüzden sınıflarına @Component ile ek açıklama ekleyemezsiniz), bu nedenle otomatik yapılandırma mümkün değildir.

@Bean açıklama bir nesne döndürür yay uygulama bağlamında fasulye olarak kayıt gerektiğini. Yöntemin vücut örneği oluşturmak için sorumlu mantık taşımaktadır.


5
Bence bu en mantıklı. Eğer doğru anlıyorsam @Componentsınıflar @Bean(sınıf nesnelerinin örneklerini veren) devam ederken sınıfları kendileri gider.
jocull

182

Bazı dinamik durumlara bağlı olarak belirli bir uygulama istediğimi düşünelim. @Beanbu durum için mükemmel.

@Bean
@Scope("prototype")
public SomeService someService() {
    switch (state) {
    case 1:
        return new Impl1();
    case 2:
        return new Impl2();
    case 3:
        return new Impl3();
    default:
        return new Impl();
    }
}

Ancak bunu yapmanın bir yolu yok @Component.


3
Bu örnek sınıfı nasıl adlandırıyorsunuz?
PowerFlower

1
@PowerFlower Bu yöntem,@Configuration
Juh_

98
  1. @ Bileşen otomatik olarak sınıf yolu taraması kullanarak çekirdekleri algılar ve yapılandırırken @Bean, Spring'in otomatik olarak yapmasına izin vermek yerine açıkça tek bir fasulye bildirir .
  2. @Component dekuple etmez @Bean olarak sınıf tanımından fasulye beyanı ayırır sınıf tanımından fasulye beyanı.
  3. @Component sınıf düzeyinde bir ek açıklama iken @Bean bir yöntem düzeyinde ek açıklamadır ve yöntemin adı fasulye adı olarak işlev görür.
  4. @Component @Configuration kullanılabilir için ihtiyaç @Bean ek açıklama olarak gereken açıklama @Configuration ile açıklamalı sınıfı içinde kullanılan .
  5. Biz fasulye oluşturamazsınız sınıf biz oysa dışarıda bahar konteyner ise, @Component kullanan bir sınıfın bir fasulye oluşturabilir sınıf varsa @Bean bile kullanan bir sınıfın dışında bahar konteyner .
  6. @Component , @Controller, @Repository ve @Service gibi farklı uzmanlıklara sahipken @Bean'ın uzmanlık alanı yoktur .

3
4. Aslında @Bean yapılandırma dışı sınıfta bildirilebilir. Lite modu olarak bilinir
voipp

1
Nokta 5 ile ilgili olarak. Bence bahar kabının içine bir fasulye koyduk. Yani, her sınıf yay konteynerinin dışında. Sanırım, puan 5 ödüllendirilmelidir
eugen

97

Her iki yaklaşım da hedef türü Bahar konteynerine kaydetmeyi amaçlamaktadır.

Fark olduğu @Beaniçin geçerlidir yöntem ise, @Componentiçin de geçerlidir türleri .

Bu nedenle @Beanek açıklama kullandığınızda , yöntemin gövdesinde örnek oluşturma mantığını denetlersiniz ( yukarıdaki örneğe bakın ). @ComponentEk açıklama ile yapamazsınız.


Tür nedir?
Jac Frall

20

Bir sürü cevap görüyorum ve hemen hemen her yerde, söz konusu @ Bileşeni, bileşenin tarandığı otomatik kablolama içindir ve @Bean tam olarak bu fasulyenin farklı şekilde kullanıldığını bildiriyor . Nasıl farklı olduğunu göstereyim.

  • @Fasulye

İlk olarak bir yöntem düzeyinde ek açıklama. İkincisi, genellikle bir java kodunda (xml yapılandırması kullanmıyorsanız) çekirdekleri yapılandırmak için kullanırsınız ve ardından ApplicationContext'in getBean yöntemini kullanarak bir sınıftan çağırırsınız. sevmek

 @Configuration
class MyConfiguration{
    @Bean
    public User getUser(){
        return new User();
    }
}

class User{
}



//Getting Bean 
User user = applicationContext.getBean("getUser");
  • @Bileşen

Özel bir fasulye değil, bir fasulyeye açıklama eklemenin genel yoludur. Sınıf düzeyinde ek açıklamadır ve java veya xml yapılandırması yoluyla tüm bu yapılandırma öğelerinden kaçınmak için kullanılır.

Böyle bir şey elde ederiz.

@Component
class User {
}

//to get Bean
@Autowired
User user;

Bu kadar . Bu fasulyeyi örneklemek ve kullanmak için tüm yapılandırma adımlarından kaçınmak için tanıtıldı.


6
Ben @Beanyaklaşım kullandığınızda UserConnect ApplicationContext almak gerekli olmadığını düşünüyorum . @AutowireFasulyeyi almak için hala kullanabilirsiniz @Component. @BeanTıpkı Fasulyeyi olduğu gibi Bahar Kaplarına ekler @Component. Fark aşağıdaki gibidir. 1. Kullanarak @Bean, Spring Container'a Üçüncü Şahıs Sınıfları ekleyebilirsiniz. 2. kullanarak @Bean, çalışma zamanında bir arabirimin istenen uygulamasını alabilirsiniz (Fabrika tasarım deseni kullanarak)
Andy

20

@BeanMevcut bir üçüncü taraf sınıfını Spring framework uygulama içeriğiniz için kullanılabilir hale getirmek için kullanabilirsiniz .

@Bean
public ViewResolver viewResolver() {

    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

    viewResolver.setPrefix("/WEB-INF/view/");
    viewResolver.setSuffix(".jsp");

    return viewResolver;
}

@BeanEk açıklamayı kullanarak, üçüncü taraf bir sınıfı (sahip olmayabilir @Componentve Bahar kullanamayabilir), Bahar çekirdeği olarak sarabilirsiniz . Ve sonra bir kez kullanılarak sarılır @Bean, tek bir nesne olarak ve Bahar çerçeve uygulama bağlamında kullanılabilir. Artık bağımlılığı enjeksiyon kullanarak ve kullanarak bu fasulye kolayca paylaşmak / yeniden kullanabilirsiniz @Autowired.

Bu yüzden @Beanek açıklama üçüncü taraf sınıfları için bir sarıcı / adaptör olduğunu düşünün . Üçüncü taraf sınıflarını Spring framework uygulama içeriğiniz için kullanılabilir hale getirmek istiyorsunuz.

@BeanYukarıdaki kodu kullanarak , açıkça tek bir fasulye bildiririm çünkü yöntemin içinde, açıkça newanahtar kelimeyi kullanarak nesneyi oluşturuyorum . Ben de verilen sınıfın setter yöntemlerini elle arıyorum. Böylece önek alanının değerini değiştirebilirim. Dolayısıyla bu manuel çalışmaya açık yaratma denir. @ComponentAynı sınıf için kullanırsam, Bahar kapsayıcısında kayıtlı fasulye önek alanı için varsayılan değere sahip olacaktır.

Öte yandan, bir sınıfa açıklama eklediğimizde @Component, newanahtar kelimeyi manuel olarak kullanmamıza gerek yoktur . Spring tarafından otomatik olarak kullanılır.


1
Bu cevap bu fasulyenin nasıl kullanıldığının bir örneği ile güncellenirse iyi olur
softarn

Kaynak kodu değiştirmeye izin vermiyorsa, bir @Bean'ı bir üçüncü taraf sınıfının üzerine nasıl sararsınız?
veritas

16

@ComponentEtiketi kullandığınızda, vanilya çekirdeği bildirim yöntemiyle (açıklamalı @Bean) bir POJO'ya (Düz Eski Java Nesnesi) sahip olmakla aynıdır . Örneğin, aşağıdaki yöntem 1 ve 2 aynı sonucu verecektir.

Yöntem 1

@Component
public class SomeClass {

    private int number;

    public SomeClass(Integer theNumber){
        this.number = theNumber.intValue();
    }

    public int getNumber(){
        return this.number;
    }
}

'theNumber' için bir fasulye ile:

@Bean
Integer theNumber(){
    return new Integer(3456);
}

Yöntem 2

//Note: no @Component tag
public class SomeClass {

    private int number;

    public SomeClass(Integer theNumber){
        this.number = theNumber.intValue();
    }

    public int getNumber(){
        return this.number;
    }
}

her ikisi için fasulye ile:

@Bean
Integer theNumber(){
    return new Integer(3456);
}

@Bean
SomeClass someClass(Integer theNumber){
    return new SomeClass(theNumber);
}

Yöntem 2, fasulye bildirimlerini bir arada tutmanıza izin verir, biraz daha esnektir vb. Vanilya olmayan bir SomeClass fasulyesi aşağıdaki gibi eklemek isteyebilirsiniz:

@Bean
SomeClass strawberryClass(){
    return new SomeClass(new Integer(1));
}

10

Fasulye üretmenin iki yolu var. Bunlardan biri ek açıklama içeren bir sınıf oluşturmaktır @Component. Diğeri ise bir yöntem oluşturmak ve üzerine açıklama eklemek @Bean. Yöntemi içeren sınıflar @Beaniçin açıklama eklenmesi @Configuration gerekir Bahar projenizi çalıştırdıktan sonra, açıklama içeren @ComponentScansınıf, @Componentüzerindeki her sınıfı tarar ve bu sınıfın örneğini Ioc Container'a geri yükler. @ComponentScanYapacağı diğer bir şey, @Beanüzerinde yöntemleri çalıştırmak ve dönüş nesnesini fasulye olarak Ioc Container'a geri yüklemektir. Dolayısıyla, mevcut durumlara bağlı olarak ne tür fasulye oluşturmak istediğinize karar vermeniz gerektiğinde,@Bean. Mantığı yazıp istediğiniz nesneyi döndürebilirsiniz. Bahsetmeye değer başka bir şey, yöntemin @Beanadı olan fasulye varsayılan adıdır.


6
  • @component ve uzmanlıkları (@Controller, @service, @repository) sınıf yolu taraması kullanarak otomatik algılamaya izin verir. @Controller, @service, @repository gibi bir bileşen sınıfı görürsek, bileşen taraması kullanılarak yay çerçevesi tarafından otomatik olarak taranır.
  • @Bean ise sadece bir yapılandırma sınıfındaki tek bir fasulyeyi açıkça belirtmek için kullanılabilir.
  • @Bean, baharın otomatik olarak yapmasına izin vermek yerine açıkça tek bir fasulye beyan ederdi. Fasulye sınıf tanımından septat deklarasyonu yapar.
  • Kısacası @Controller, @service, @repository otomatik algılama içindir ve @Bean sınıftan ayrı fasulye oluşturmak içindir
    - @Kontrolör
    genel sınıf LoginController 
    {--code--}

    - @Yapılandırma
    herkese açık sınıf AppConfig {
    @Fasulye
    kamu SessionFactory sessionFactory () 
    {--code--}

3

@Bean, Spring ve iş kurallarınızı derleme zamanında birleştirmekten kaçınmak için oluşturuldu. Bu, iş kurallarınızı PlayFramework veya JEE gibi diğer çerçevelerde yeniden kullanabileceğiniz anlamına gelir.

Ayrıca, varsayılan Bahar örneğinin yeterli olmadığı fasulye oluşturma konusunda tam kontrole sahipsiniz.

Bunun hakkında konuşan bir yazı yazdım.

https://coderstower.com/2019/04/23/factory-methods-decoupling-ioc-container-abstraction/



1

1. About @Component
@Component @Configuration'a benzer şekilde çalışır.

Her ikisi de açıklamalı sınıfın bir veya daha fazla fasulyeye kayıtlı olması gerektiğini belirtir Spring-IOC-Container.

@Component tarafından ek açıklamalı sınıf olarak adlandırıyoruz Component of Spring. Birkaç fasulye içeren bir kavramdır.

Component class'nin bu fasulyesini kaydetmek için Spring tarafından otomatik olarak taranması gerekir component class.

2. Hakkında @Bean
@Bean yöntemi component-class(yukarıda belirtildiği gibi) açıklama eklemek için kullanılır . Açıklamalı yöntemle geri gönderilen örneğin kaydedilmesi gerektiğini belirtir Spring-IOC-Container.

3. Sonuç
İkisi arasındaki fark nispeten elverişlidir, kullanılır different circumstances. Genel kullanım:

    // @Configuration is implemented by @Component
    @Configuration
    public ComponentClass {

      @Bean
      public FirstBean FirstBeanMethod() {
        return new FirstBean();
      }

      @Bean
      public SecondBean SecondBeanMethod() {
        return new SecondBean();
      }
    }

0

Yukarıdaki cevaplardan Ek Noktalar

Diyelim ki birden fazla uygulamada paylaşılan ve birkaç hizmet içeren bir modülümüz var. Her uygulama için hepsine gerek yoktur.

Bu hizmet sınıflarında @Component ve uygulamada bileşen taraması kullanıyorsanız,

sonuçta gereğinden fazla fasulye tespit edebiliriz

Bu durumda, bileşen taramasının filtrelemesini ayarlamanız veya kullanılmayan çekirdeklerin bile çalışabileceği yapılandırmayı sağlamanız gerekiyordu. Aksi takdirde, uygulama içeriği başlamaz.

Bu durumda, @Bean ek açıklaması ile çalışmak ve sadece bu fasulyeleri somutlaştırmak daha iyidir,

her uygulamada ayrı ayrı gerekli olan

Bu nedenle, esas olarak, bağlama üçüncü taraf sınıfları eklemek için @Bean kullanın. Ve @Component, tek uygulamanızın içindeyse.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.