Springライフサイクルの3つの方法とソースの分析
36298 ワード
記事の目次の3つの方法 コード例 実行結果 @Scrope("singleton")--単一例 @Scope--プロトタイプ ソースコード解析 初期化方法 廃棄方法 3つの方法@Ben指定初期化と廃棄方法 InitializingBenとDispable Bean を実現します.@PostConstruct&@Predestry まず、実行順の初期化の実行手順3>2>1の破壊の実行手順3>2>1のソースコードを分析します.
コードの例
以下は3つの方法を一緒に使って、彼らの実行順を確認します.
beanの役割領域を変更する
@Scope(「singleton」)–単一例
プロトタイプのbeanは呼び出し時のみ初期化されますので、aplication Contact.getBeanがなければ、userは初期化されません.beanFactoryに任せずに管理されますので、廃棄方法は実行されません.
キーコードはソースのコメントに書いてあります.
初期化の方法
順番に次の方法に進みます. org.springframe ework.com ntxt.support.AbstractAplication Contatext龚refresh org.springframewark.com ntxt.support.AbstractAplication Contect t龚finish BeanFactory Initialization org.spring frame ewark.beans.factory.co.figc.onfigrable Listable Beable Factory啱pre InstantiateSingletos org.spring frame ewark.beans.factory.support.AbstractBeabin Factory啷ゲトビーン(java.lang.String) org.springframe ewark.beans.factory.support.AbstractBenFactory咻doGetBen org.spring frame ewark.beans.factory.support.AbstractBenFactory咻createBen org.springframe ebook.beans.factory.support.AbstractAutowireCable BenFactory org.spring frame ewark.beans.factory.support.Abstract AutowireCable BenFactory.java.lang.String,java.lang.Object,ort.org.sprigframe.bern.Beatonict.Ropt.246
appication Contect.close()は最終的に次のような方法org.spring frame ebook.beans.factory.support.Dispposable BenAdapterを実行します.
注釈を見る
コードの例
以下は3つの方法を一緒に使って、彼らの実行順を確認します.
/**
* @desc
*/
@Component
public class Role {
public Role() {
System.out.println("role===============");
}
}
public class User implements InitializingBean, DisposableBean {
@Autowired
private Role role;
public User() {
System.out.println("user--constructor");
}
public void aaa() {
System.out.println("user--aaa");
}
public void bbb() {
System.out.println("user--bbb");
}
@Override
// DisposableBean
public void destroy() throws Exception {
System.out.println("user++destory");
}
@Override
// InitializingBean
public void afterPropertiesSet() throws Exception {
System.out.println("user++init");
}
@PostConstruct
public void postConstructor() {
System.out.println("postConstructor");
}
@PreDestroy
public void preDestory() {
System.out.println("preDestory");
}
}
@Configuration
@ComponentScan("com.demo.init")
public class Test {
// Bean
@Bean(initMethod = "aaa",destroyMethod = "bbb")
// @Scope("prototype")
public User get(){
return new User();
}
}
//
public class Start {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Test.class);
applicationContext.getBean(User.class);
System.out.println("applicationContext will close");
applicationContext.close();
}
}
実行結果beanの役割領域を変更する
@Scope(「singleton」)–単一例
role===============
user--constructor
@postConstructor
InitializingBean++init
bean init aaa
applicationContext will close
@preDestory
DisposableBean++destory
bean destory bbb
@Scope(「prototype」)–プロトタイププロトタイプのbeanは呼び出し時のみ初期化されますので、aplication Contact.getBeanがなければ、userは初期化されません.beanFactoryに任せずに管理されますので、廃棄方法は実行されません.
role===============
user--constructor
@postConstructor
InitializingBean++init
bean init aaa
applicationContext will close
ソース分析キーコードはソースのコメントに書いてあります.
初期化の方法
順番に次の方法に進みます.
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// @PostConstruct CommonAnnotationBeanPostProcess
// BeanPostProcessor
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 1.2 ,
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//
// InitializingBean afterPropertiesSet()
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// @Bean init
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
廃棄方法appication Contect.close()は最終的に次のような方法org.spring frame ebook.beans.factory.support.Dispposable BenAdapterを実行します.
注釈を見る
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
// @PreDestroy
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
if (this.invokeDisposableBean) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
}
else {
// DisposableBean destroy()
((DisposableBean) this.bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
if (this.destroyMethod != null) {
// @Bean
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}