@Bean etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
@Bean etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

7 Ağustos 2019 Çarşamba

SpringContext @Bean Anotasyonu

Giriş
Şu satırı dahil ederiz.
import org.springframework.context.annotation.Bean;
Metod Seviyesinde Kullanılır
Açıklaması şöyle
This annotation is used at the method level. The @Bean annotation works with @Configuration to create Spring beans.
@Autowired İle Farkı
Açıklaması şöyle. Yani @Bean bir producer, @Autowired ise consumer olarak düşünülebilir.
@Bean tells Spring 'here is an instance of this class, please keep hold of it and give it back to me when I ask'.
@Autowired says 'please give me an instance of this class, for example, one that I created with an @Bean annotation earlier'.
Bu anotasyon sayesinde kendi sınıfımza anotasyon eklemek zorunda kalmıyoruz. Eskiden şöyle yapardık.
@Component
public class MyClass{   
  public MyClass (){
    ...
  }
}
destroyMethod Alanı
Açıklaması şöyle. Çağrılmasını istediğimiz metodu belirtmek için @PreDestroy da kullanılabilir
In other words, if you don't specify destroyMethod, but the bean has a public close() or shutdown() method, it will be automatically used as the destroy-method
Örnek
Şöyle yaparız.
@Bean(initMethod="start",destroyMethod="stop")
public org.h2.tools.Server h2WebConsonleServer () throws SQLException {
  return org.h2.tools.Server.createWebServer("-web","-webAllowOthers","- 
  webDaemon","-webPort", "8082");
}
initMethod Alanı
Şöyle yaparız.
@Bean(initMethod = "doProvision")
public Provisioner provisioner() {
  return new Provisioner();
}
name Alanı
Belirtilen isme sahip bean yaratır. Bu bean'e kodun diğer yerlerinde @Autowired + @Qualifier ile erişilir.

Örnek
Şöyle yaparız.
@Configuration
@ComponentScan({"my.packages"})
public class AppManager {

  @Bean(name = "jmxExporter")
  public Exporter jmxExporter() {
    return new Exporter();
  }
}
Örnek
Aynı tipten farklı isime sahip 3 tane bean yaratmak için şöyle yaparız.
@Service("Service-A")
public class SampleService {
    public String doSomething() { return "Foo"; }
}

@Configuration
public class SampleConfig {

  @Bean(name = {"Service-B", "Service-C"})
  public SampleService createMirroredService(@Autowired SampleService service) {
    return service;
  }
}

5 Temmuz 2019 Cuma

@Configuration Anotasyonlu Sınıfta @Bean ve Diğer Beanlere Dependency - Full Mode

Giriş
Klasik @Configuration kullanımında @Bean olarak işaretli metoda gerekli diğer bean'leri metod çağrısı ile almak yeterli.

Ancak istenirse parametre olarak geçmek te mümkün.
İlave olarak bazen field olarak ta kullanılabiliyor.

1. Metod Çağrısı - Full Mode
Bu Yöntem Sadece @Configuration Sınıfında Kullanılmalı
Çünkü @Configuration içindeki @Bean ve @Component içindeki @Bean farklı şeyler. Spring bu moda Full Mode diyor. Açıklaması şöyle.
Full @Configuration vs 'lite' @Beans mode?
When @Bean methods are declared within classes that are not annotated with @Configuration they are referred to as being processed in a 'lite' mode. For example, bean methods declared in a @Component or even in a plain old class will be considered 'lite'. 

Unlike full @Configuration, lite @Bean methods cannot easily declare inter-bean dependencies. Usually one @Bean method should not invoke another @Bean method when operating in 'lite' mode. 

Only using @Bean methods within @Configuration classes is a recommended approach of ensuring that 'full' mode is always used. This will prevent the same @Bean method from accidentally being invoked multiple times and helps to reduce subtle bugs that can be hard to track down when operating in 'lite' mode.
Yani @Configuration ve @Component içindeki @Bean'ler farklı şeyler. Açıklaması şöyle.
Spring does actually use ASM (embedded in the spring-core dependency) to load and process @Configuration classes. This is also the main difference in processing @Bean methods in @Configuration and @Component classes.
@Configuration aslında proxy gibi çalışıyor. Dolayısıyla metod çağrısı her zaman aynı bean'i dönüyor. Açıklaması şöyle.
With @Configuration you will get the same and proxied object. With @Component you are running in so called lite mode, you will get a proxy but when calling the simpleBean() multiple times you will get a fresh proxied instance for each call.
Örnek
Açıklaması şöyle.
When @Bean have dependencies on one another, then to resolve this dependency one bean method can call the other one.
Şöyle yaparız.
@Bean
public Dog dog() {
  ...
  return dog;
}

@Bean
public DogHouse dogHouse() {
  Dog d = dog(); 
  ...
  return dogHouse;
}
Örnek
Şöyle yaparız
@Configuration
public class Config {
  @Bean
  public SimpleBean simpleBean() {
    return new SimpleBean();
  }

  @Bean
  public SimpleBeanConsumer simpleBeanConsumer() {
    return new SimpleBeanConsumer(simpleBean());
  }

  @Bean
  public AnotherBeanConsumer anotherBeanConsumer() {
    return new AnotherBeanConsumer(simpleBean());
  }        
 }
Örnek
Şöyle yaparız.
@Configuration 
public class Config {

  @Bean
  public FooUser fooUser() {
    return new FooUser(foo());
  }

  @Bean
  public FooFactory fooFactory() {
    return new FooFactory();
  }

  @Bean
  public Foo foo() {
    return fooFactory().createFoo();
  }
}
2. Parametre
Bu kullanımın çok bir özelliği yok. Klasik bean kullanımı

Örnek
Şöyle yaparız.
@Bean
public DogHouse dogHouse(Dog d) {
  ...
  return dogHouse;
}
3. Field Injection
Örnek 
Şöyle yaparız. Burada @Bean için gereken diğer bean Field Injection ile geliyor.
@SpringBootApplication
public class Application {

  @Autowired
  BookingService bookingService;

  @Bean
  BookingService bookingService() {
    return new BookingService();
  }
  ...  
}