วิธีการเริ่มต้นใน Spring Controller (เวอร์ชันหมายเหตุประกอบ)


106

ฉันกำลังแปลงคอนโทรลเลอร์เป็นเวอร์ชันคำอธิบายประกอบที่ใหม่กว่า ในเวอร์ชันเก่าฉันเคยระบุเมธอด init ใน springmvc-servlet.xml โดยใช้:

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

ฉันจะระบุเมธอด init โดยใช้เวอร์ชันคำอธิบายประกอบได้อย่างไร


คำตอบ:


240

คุณสามารถใช้ได้

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

1
คุณพูดถูกแล้ว "คำอธิบายประกอบทั่วไป 1.0", Java1.7 ก็ใช้งานได้เช่นกัน
Grim

หากคุณต้องการใช้ผู้ใช้จาก SecurityContextHolder ในช่วงเวลา PostConstruct จะไม่เริ่มต้น จำเป็นต้องใช้เหมือนวิธีการไร้สัญชาติ (getUser () ... {return Security ... user ();}
Joao Polo

ภาครัฐหรือเอกชน
anshulkatta

20

หรือคุณสามารถให้คลาสของคุณใช้InitializingBeanอินเทอร์เฟซเพื่อจัดเตรียมฟังก์ชันการเรียกกลับ ( afterPropertiesSet()) ซึ่ง ApplicationContext จะเรียกใช้เมื่อสร้าง bean


4

มีหลายวิธีในการสกัดกั้นกระบวนการเริ่มต้นใน Spring หากคุณต้องเริ่มต้นถั่วทั้งหมดและกำหนดเส้นทางอัตโนมัติ / ฉีดมีอย่างน้อยสองวิธีที่ฉันรู้ว่าจะทำให้มั่นใจได้ ฉันมีเพียงทดสอบอันที่สอง แต่ฉันเชื่อว่าทั้งสองทำงานเหมือนกัน

หากคุณใช้ @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 เป็นกรอบงานที่เลือก ระบบเก่านำการอ้างอิงแบบวงกลมจำนวนมากมาสู่ตารางดังนั้นฉันจึงต้องใช้ setter-dependency เป็นจำนวนมาก นั่นทำให้ฉันปวดหัวเนื่องจากฉันไม่สามารถไว้วางใจ @PostConstruct ได้เนื่องจากยังไม่ได้ทำการป้อนอัตโนมัติ / การฉีดโดย setter คำสั่งคือตัวสร้าง @PostConstruct จากนั้นตัวตั้งค่าอัตโนมัติ ฉันแก้ไขมันด้วยคำอธิบายประกอบ @EventListener ซึ่งจะทำงานล่าสุดและในเวลา "เดียวกัน" สำหรับถั่วทั้งหมด ตัวอย่างแสดงการใช้งาน InitializingBean เช่นกัน

ฉันมีสองคลาส (@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
   }

}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.