DerekYRC / DerekYRC/mini-spring

初始化与销毁方法中,只避免销毁方法执行两次而初始化方法没有相关的判断

Open
#63 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
6.4k
Forks
1.4k
PR merge metrics
No merged PRs in 30d

Description

DisposableBeanAdapter#destroy() 会通过判断避免 bean 继承自 DisposableBean ,且自定方法与 DisposableBean 方法同名导致销毁方法方法执行两次,代码如下
```java
@Override
public void destroy() throws Exception {
if (bean instanceof DisposableBean) {
((DisposableBean) bean).destroy();
}

//避免同时继承自DisposableBean,且自定义方法与DisposableBean方法同名,销毁方法执行两次的情况
if (StrUtil.isNotEmpty(destroyMethodName) && !(bean instanceof DisposableBean && "destroy".equals(this.destroyMethodName))) {
//执行自定义方法
Method destroyMethod = ClassUtil.getPublicMethod(bean.getClass(), destroyMethodName);
if (destroyMethod == null) {
throw new BeansException("Couldn't find a destroy method named '" + destroyMethodName + "' on bean with name '" + beanName + "'");
}
destroyMethod.invoke(bean);
}
}
```
而 AbstractAutowireCapableBeanFactory#invokeInitMethods() 中缺少类似判断,会导致初始化方法执行两次,代码如下
```java
protected void invokeInitMethods(String beanName, Object bean, BeanDefinition beanDefinition) throws Throwable {
if (bean instanceof InitializingBean) {
((InitializingBean) bean).afterPropertiesSet();
}
String initMethodName = beanDefinition.getInitMethodName();
if (StrUtil.isNotEmpty(initMethodName)) {
Method initMethod = ClassUtil.getPublicMethod(beanDefinition.getBeanClass(), initMethodName);
if (initMethod == null) {
throw new BeansException("Could not find an init method named '" + initMethodName + "' on bean with name '" + beanName + "'");
}
initMethod.invoke(bean);
}
}
```
在查看spring-framework 5.3.x 源码后可以发现源码是做了相关的判断的,如下
```java
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {

boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
// 在这里做了判断
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.