@PostConstructEk açıklamayı kullanmak init-methodile Spring XML yapılandırmasında olduğu gibi aynı yöntemi bildirmek arasında herhangi bir fark var mı ?
Yanıtlar:
Hayır, pratikte bir fark olduğunu düşünmüyorum ama çalışma şekillerinde öncelikler var. @PostConstruct, init-methodBeanPostProcessors.
@PostConstructbir JSR-250 ek açıklaması iken init-method, Spring'in bir başlatma yöntemine sahip olma şeklidir.@PostConstructyönteminiz varsa, bu, başlatma yöntemleri çağrılmadan önce çağrılacaktır.afterPropertiesSet, önce @PostConstructçağrılır, sonra afterPropertiesSetve sonra init-method.Daha fazla bilgi için Spring'in referans belgelerine bakabilirsiniz .
JSR 250 spesifikasyonlarından önce, java sınıflarını (fasulye) herhangi bir yaya özgü sınıflardan / ek açıklamalardan ayırdığı için xml'de init yönteminin kullanılması tercih ediliyordu. daha sonra init yönteminin kullanılması tercih edildi. u oluşturma yöntemi sırasında başlatma yöntemi olarak çağrılması gereken yöntemi belirtebilirsiniz.
Şimdi Java EE'de JSR 250 spesifikasyonlarının eklenmesi ve bu açıklamaların yay desteğiyle, yay çerçevesine bağımlılık bir dereceye kadar azaltıldı.
Ancak itiraf etmeliyim ki bu şeylerin eklenmesi kodun okunabilirliğini arttırır, yani her iki yaklaşımın da artıları ve eksileri vardır.
Gerçek bir fark yok. Sisteminizi nasıl yapılandırmayı tercih ettiğinize bağlıdır ve bu kişisel bir seçim meselesidir. Ben @PostConstructde kendi kodum için ek açıklamaları kullanmayı tercih ederim (çünkü çekirdek yalnızca yöntem çağrıldıktan sonra doğru şekilde yapılandırılır) ve init-methodBahar ile uyumlu olmayan kitaplıklardan fasulye örneğini oluştururken kullanırım (elbette notları orada uygulayamam!) ama her şeyi öyle ya da böyle yapmak isteyen insanları tamamen anlayabiliyorum.
@postconstruct, baharın bir parçası değil. Javax paketinin bir parçasıdır. İkisi de aynı. init-yöntemini kullanarak xml dosyasına eklememiz gerekir. @postconstruct kullanırsanız, xml'ye eklemeniz gerekmez. Aşağıdaki makaleye göz atın.
Aşağıdaki Bean Creation Life-Cycle Callback şemasında görebileceğiniz gibi .
Bu 3 adım Bean Creation Life-Cycle Callback'te gerçekleşir:
@PostConstruct.InitializingBean, afterPropertiesSet()çağrılacaktır.init-methodveya @Bean(initmethod="..")daha sonra init yöntemini çağırır.Bu şema Pro Spring 5'ten alınmıştır: Yay Çerçevesi ve Araçlarına Yönelik Kapsamlı Bir Kılavuz
Orada olabilir arasındaki farkı @PostConstructve init-methodçünkü @PostConstructiçinde ele alınır postProcessAfterInitializationfasulye başlatma (aşamasından AbstractAutowireCapableBeanFactory.initializeBean()tarafından yöntemi) CommonAnnotationBeanPostProcessorise, inityöntem tamamlandıktan sonra çağrılan postProcessBeforeInitializationfazda (bu konuda ve başlangıcından önce, postProcessAfterInitializationfaz).
DÜZENLEME : Yani, sıra şu şekildedir : 1) postProcessBeforeInitializationaşama, 2) inityöntem çağrılır, 3) postProcessAfterInitializationaşama, @PostConstructyöntemi çağırır
(Yan not olarak, kabul edilen cevaptan bir açıklama
@PostConstruct, init yöntemi BeanPostProcessors'tır
tam olarak doğru değil: @PostConstructa tarafından işleniyor BeanPostProcessor, inityöntem değil.)
Daha sonra çalıştırılmak üzere ( ) ile yapılandırılan bazılarının (potansiyel olarak özel) yönteminde ciddi bir şey yapması durumunda fark olacaktır .
Orada hayır varsayılan Bahar yapılandırma ile herhangi bir farklılık çünkü tüm sonra uygulanmak üzere konfigüre edildiği , içinde bir şey yapmayın yöntemle.BeanPostProcessorOrdered.getOrder()CommonAnnotationBeanPostProcessorpostProcessBeforeInitializationBeanPostProcessorsBeanPostProcessorsCommonAnnotationBeanPostProcessorpostProcessBeforeInitialization
Sonuç olarak, kabul edilen cevap ve benzerleri doğrudur ... vakaların% 99'unda ve bu gönderi sadece "şeytan ayrıntıda gizlidir" kavramına bir haraç ödemektir.
Tam kod burada: https://github.com/wkaczurba/so8519187 ( yaylı önyükleme )
Ek açıklamaları kullanma:
@Slf4j
@Component
public class MyComponent implements InitializingBean {
@Value("${mycomponent.value:Magic}")
public String value;
public MyComponent() {
log.info("MyComponent in constructor: [{}]", value); // (0) displays: Null
}
@PostConstruct
public void postConstruct() {
log.info("MyComponent in postConstruct: [{}]", value); // (1) displays: Magic
}
@Override // init-method; overrides InitializingBean.afterPropertiesSet()
public void afterPropertiesSet() {
log.info("MyComponent in afterPropertiesSet: [{}]", value); // (2) displays: Magic
}
@PreDestroy
public void preDestroy() {
log.info("MyComponent in preDestroy: [{}]", value); // (3) displays: Magic
}
}
Bizi alır:
Org.springframework.context yenileniyor ...
Yapıcıda MyComponent : [null] postConstruct'ta [null] MyComponent: [Magic]
AfterPropertiesSet içinde MyComponent: [Magic]
...
Başlangıçta JMX pozlaması için fasulye kaydediliyor
DemoApplication 0,561 saniyede başlatıldı (JVM 1.011 için çalışıyor)
org.springframework.context kapatılıyor .. . Kapatma sırasında JMX'e maruz kalan çekirdeklerin kaydı siliniyor
...
Ön Yıkımda MyComponent: [Magic]