18 Kasım 2022 Cuma

Bean Lifecycle

1. Spring LifeCycle
Şeklen şöyle. Bu şekil SpringBoot değil, Spring bakış açısına sahip

1. Instantiate by container

2. Populate Attributes
Açıklaması şöyle. XML ile property set edilince kullanılır
Spring injects dependencies into the bean attributes according to BeanDefinition.
3. Inject Aware interfaces 
Açıklaması şöyle
Spring detects if the object implements any xxAware interfaces and injects the corresponding instances into the bean.
Sınıfım bazı Spring arayüzlerinden kalıtır. Örneğin şunlar. Aware arayüzleri arasında bir sıralama var sanırım

4. BeanPostProcessor
Açıklaması şöyle
If you want to customize some logic before the beans are actually used, you can implement it through the BeanPostProcessor interface, which mainly provides two methods:

- postProcessBeforeInitialization (Object bean, String beanName)
- postProcessAfterInitialization (Object bean, String beanName)
BeanPostProcessor sınıfından kalıtan ayrı bir sınıf yazılır. Bazı sınıflar hazır geliyor. Örneğin

5. InitializingBean and init-method
Açıklaması şöyle
InitializingBean interface only has one function:

afterPropertiesSet()
We can also configure init-method in bean to define the method name for execution.
Sınıfım  InitializingBean arayüzünü gerçekleştirir. Bence @PostConstruct gibi düşünülebilir.

6. BeanPostProcessor
postProcessAfterInitialization (Object bean, String beanName) metodu çağrılır
BeanPostProcessor sınıfından kalıtan ayrı bir sınıf yazılır

7. Ready for use
Bean artık hazırdır

8. DisposableBean and destroy-method
Bean artık yok edilecektir. Açıklaması şöyle. Sınıfım DisposableBean arayüzünü gerçekleştirilir
Same as init-method, we can use DisposableBean and destroy-method to appoint a method for destruction.
Örnek
Elimizde şöyle bir kod olsun.
public class PersonBean implements BeanNameAware, BeanFactoryAware, InitializingBean,
DisposableBean {
  private Integer id;
  private String name;

  public PersonBean(){
    System.out.println("1. I am alive!");
  }

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
    System.out.println("2. Populate attribute: my name is " + name);
  }

  @Override
  public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    System.out.println("4. Invoking BeanFactoryAware#setBeanFactory method");
  }

  @Override
  public void setBeanName(String s) {
    System.out.println("3. Invoking BeanNameAware#setBeanName method");
  }

  public void init(){
    System.out.println("7. Customized init method");
  }

  public void myDestroy(){
    System.out.println("10. Customized destroy method");
  }

  @Override
  public void destroy() throws Exception {
    System.out.println("9. DisposableBean#destroy method");
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    System.out.println("6. InitializingBean#afterPropertiesSet method");
  }
}
Ayrı bir BeanPostProcessor sınıfı olsun.
public class MyBeanPostProcessor implements BeanPostProcessor {

  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName)
  throws BeansException {
    System.out.println("5. BeanPostProcessor#postProcessBeforeInitialization method");
    return bean;
  }

  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName)
  throws BeansException {
    System.out.println("8. BeanPostProcessor#postProcessAfterInitialization method");
    return bean;
  }
}
Elimizde şöyle bir XML olsun
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean name="myBeanPostProcessor" class="com.dntech.demo.config.MyBeanPostProcessor"/>
    <bean name="personBean" class="com.dntech.demo.dao.PersonBean"
          init-method="init" destroy-method="myDestroy">
        <property name="id" value="123456"/>
        <property name="name" value="dntech"/>
    </bean>
</beans>
public static void main(String[] args){
  ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
  PersonBean personBean = (PersonBean) context.getBean("personBean");
  ((ClassPathXmlApplicationContext) context).destroy();
}
Çıktı şöyle
1. I am alive!
2. Populate attribute: my name is dntech
3. Invoking BeanNameAware#setBeanName method
4. Invoking BeanFactoryAware#setBeanFactory method
5. BeanPostProcessor#postProcessBeforeInitialization method
6. InitializingBean#afterPropertiesSet method
7. Custom init method
8. BeanPostProcessor#postProcessAfterInitialization method
9. DisposableBean#destroy method
10. Customized destroy method
2. SpringBoot LifeCycle
Bir başka şekil şöyle. Bu şekil SpringBoot bakış açısına sahip. Burada Instantiate by container + Populate Attributes yerine Inject Dependencies denilmiş. Kasıt şu, constructor injection veya field injection varsa bunlar yapılır. Ayrıca

Bean yaratılırken @PostConstruct anostayonu initMethod'dan önce çağrılır. 
Örnek
Elimizde şöyle bir kod olsun
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
public Author author() {
  return new Author("Aplha, Engineer", "alphaengineer@gmail.com");
}

@Getter
@Setter
@NoArgsConstructor
public class Author implements BeanNameAware, BeanClassLoaderAware, 
  ApplicationContextAware, InitializingBean, DisposableBean {
 
 public Author(String fullName, String email) {
  System.out.println("constructor");
  ...
 }

 @PostConstruct
 public void init() {
  System.out.println("@PostConstruct annotated method");
 }

 @PreDestroy
 public void predestroy() {
  System.out.println("@PreDestroy annotated method");
 }

 @Override
 public void destroy() {
  System.out.println("destroy method from DisposableBean interface");
 }

 public void initMethod() {
  System.out.println("initMethod method");
 }

 public void destroyMethod() {
  System.out.println("destroyMethod method");
 }

 @Override
 public void setBeanName(String name) {
  System.out.println("setBeanName from BeanNameAware interface");
 }

 @Override
 public void setBeanClassLoader(ClassLoader classLoader) {
  System.out.println("setBeanClassLoader from BeanClassLoaderAware interface");
 }

 @Override
 public void setApplicationContext(ApplicationContext applicationContext) 
 throws BeansException {
  System.out.println("setApplicationContext from ApplicationContextAware interface");
 }

 @Override
 public void afterPropertiesSet() throws Exception {
  System.out.println("afterPropertiesSet from InitializingBean interface");
 }
}
Çıktı şöyle
constructor
setBeanName from BeanNameAware interface
setBeanClassLoader from BeanClassLoaderAware interface
setApplicationContext method ApplicationContextAware interface @PostConstruct annotated method afterPropertiesSet method InitializingBean interface initMethod method ... @PreDestroy annotated method destroy method from DisposableBean interface destroyMethod method





Hiç yorum yok:

Yorum Gönder