Метод Init у Spring Controller (версія анотації)


105

Я перетворюю контролер на новішу версію анотацій. У старій версії я вказував метод init у springmvc-servlet.xml, використовуючи:

<beans>
    <bean id="myBean" class="..." init-method="init"/>
</beans>

Як я можу вказати метод init за допомогою версії анотацій?


Дивіться також stackoverflow.com/questions/1088550
skaffman

Відповіді:


238

Можна використовувати

@PostConstruct
public void init() {
   // ...
}

1
Ви праві, його "Загальні анотації 1.0", також працюватиме Java1.7.
Грим

Якщо вам потрібно скористатися користувачем із SecurityContextHolder, в момент PostConstruct він не ініціалізується. Це потрібно використовувати як метод без громадянства. (getUser () ... {return Security ... user ();}
Жоао Поло

державне або приватне
anshulkatta

20

Крім того, ви можете запропонувати вашому класу реалізувати InitializingBeanінтерфейс, щоб забезпечити функцію зворотного виклику ( afterPropertiesSet()), до якої застосується ApplicationContext, коли bean побудований.


4

Існує кілька способів перехоплення процесу ініціалізації навесні. Якщо вам доведеться ініціалізувати всі боби та автопроводити / вводити їх, є, принаймні, два способи, які я знаю, що це забезпечать. У мене є лише тестування другого, але я вірю, що обидва працюють однаково.

Якщо ви використовуєте @Bean, ви можете посилатися на initMethod, як це.

@Configuration
public class BeanConfiguration {

  @Bean(initMethod="init")
  public BeanA beanA() {
    return new BeanA();
  }
}

public class BeanA {

  // method to be initialized after context is ready
  public void init() {
  }

} 

Якщо ви використовуєте @Component, ви можете коментувати коментарі таким чином @EventListener.

@Component
public class BeanB {

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
  }
}

У моєму випадку у мене є спадщина система, де я зараз використовую IoC / DI, де Spring Boot є обраною рамкою. Стара система приносить до таблиці багато кругових залежностей, і тому я мушу дуже багато використовувати сеттер-залежність. Це дало мені певні головні болі, оскільки я не міг довіряти @PostConstruct, оскільки автопровід / ін'єкція сетером ще не робився. Порядок - конструктор, @PostConstruct, а потім автоматичне встановлення. Я вирішив це за допомогою анотації @EventListener, яка працюватиме останньою та в той самий час для всіх бобів. Приклад показує реалізацію ініціалізаціїBean.

У мене є два класи (@Component) залежно один від одного. Для цього прикладу класи виглядають однаково, відображаючи лише один із них.

@Component
public class BeanA implements InitializingBean {
  private BeanB beanB;

  public BeanA() {
    log.debug("Created...");
  }

  @PostConstruct
  private void postConstruct() {
    log.debug("@PostConstruct");
  }

  @Autowired
  public void setBeanB(BeanB beanB) {
    log.debug("@Autowired beanB");
    this.beanB = beanB;
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    log.debug("afterPropertiesSet()");
  }

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
    log.debug("@EventListener");
  } 
}

Це вихідний журнал, що показує порядок викликів при запуску контейнера.

2018-11-30 18:29:30.504 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : Created...
2018-11-30 18:29:30.509 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : Created...
2018-11-30 18:29:30.517 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @Autowired beanA
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : afterPropertiesSet()
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @Autowired beanB
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : afterPropertiesSet()
2018-11-30 18:29:30.607 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @EventListener
2018-11-30 18:29:30.607 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @EventListener

Як ви бачите, @EventListener запускається останнім після того, як все буде готове та налаштовано.


-2
public class InitHelloWorld implements BeanPostProcessor {

   public Object postProcessBeforeInitialization(Object bean,
             String beanName) throws BeansException {
       System.out.println("BeforeInitialization : " + beanName);
       return bean;  // you can return any other object as well
   }

   public Object postProcessAfterInitialization(Object bean,
             String beanName) throws BeansException {
       System.out.println("AfterInitialization : " + beanName);
       return bean;  // you can return any other object as well
   }

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.