Spring版本
5.2.5.RELEASE
源码解析
1. DisposableBeanAdapter
public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
List<BeanPostProcessor> postProcessors, @Nullable AccessControlContext acc) {
Assert.notNull(bean, "Disposable bean must not be null");
this.bean = bean;
this.beanName = beanName;
this.invokeDisposableBean =
(this.bean instanceof DisposableBean && !beanDefinition.isExternallyManagedDestroyMethod("destroy"));
this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
this.acc = acc;
// 对destroyMethodName进行推断
String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
// 1、推断结果不为空
// 2、invokeDisposableBean为false,或者destroyMethodName = destroy
// 3、destroyMethodName不由beanDefinition进行外部管理(看方法名是这个意思,不代表正确说法)
if (destroyMethodName != null && !(this.invokeDisposableBean && "destroy".equals(destroyMethodName)) &&
!beanDefinition.isExternallyManagedDestroyMethod(destroyMethodName)) {
this.destroyMethodName = destroyMethodName;
// 通过destroyMethodName获取到对应的method
Method destroyMethod = determineDestroyMethod(destroyMethodName);
if (destroyMethod == null) {
// 如果destroyMethod为空,但是beanDefinition有强制要求执行销毁方法,此时抛出异常
if (beanDefinition.isEnforceDestroyMethod()) {
throw new BeanDefinitionValidationException("Could not find a destroy method named '" +
destroyMethodName + "' on bean with name '" + beanName + "'");
}
}
else {
Class<?>[] paramTypes = destroyMethod.getParameterTypes();
if (paramTypes.length > 1) {
// 销毁方法参数个数不能多于1个
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has more than one parameter - not supported as destroy method");
}
else if (paramTypes.length == 1 && boolean.class != paramTypes[0]) {
// 销毁方法的唯一参数只能是boolean类型
throw new BeanDefinitionValidationException("Method '" + destroyMethodName + "' of bean '" +
beanName + "' has a non-boolean parameter - not supported as destroy method");
}
// 获取接口方法
destroyMethod = ClassUtils.getInterfaceMethodIfPossible(destroyMethod);
}
this.destroyMethod = destroyMethod;
}
// 从postProcessors查找到所有适用于bean的销毁processors
this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
}
构造方法中,除了一些简单的赋值之类,还有几个处理方法:
首先通过inferDestroyMethodIfNecessary
推算出销毁方法名称,如果方法名称同时满足以下三个条件:
- 不为空
-
invokeDisposableBean
为false
,或者destroyMethodName = destroy
-
destroyMethodName
不由beanDefinition
进行外部管理(看方法名是这个意思,不代表正确说法)
那么,通过destroyMethodName
去获取销毁方法destroyMethod
,之后通过destroyMethod
获取接口层面上destroyMethod
,最后从postProcessors
查找到所有适用于bean
的销毁processors
2. inferDestroyMethodIfNecessary
@Nullable
private String inferDestroyMethodIfNecessary(Object bean, RootBeanDefinition beanDefinition) {
String destroyMethodName = beanDefinition.getDestroyMethodName();
// 如果destroyMethodName是INFER_METHOD,那么推断出真正的destroyMethodName
if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName) ||
(destroyMethodName == null && bean instanceof AutoCloseable)) {
// Only perform destroy method inference or Closeable detection
// in case of the bean not explicitly implementing DisposableBean
if (!(bean instanceof DisposableBean)) {
try {
// 获取close方法
return bean.getClass().getMethod(CLOSE_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex) {
try {
// 没有close方法,则获取shutdown方法
return bean.getClass().getMethod(SHUTDOWN_METHOD_NAME).getName();
}
catch (NoSuchMethodException ex2) {
// no candidate destroy method found
}
}
}
return null;
}
return (StringUtils.hasLength(destroyMethodName) ? destroyMethodName : null);
}
3. determineDestroyMethod
@Nullable
private Method determineDestroyMethod(String name) {
try {
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedAction<Method>) () -> findDestroyMethod(name));
}
else {
// 查找对应于name的方法
return findDestroyMethod(name);
}
}
catch (IllegalArgumentException ex) {
throw new BeanDefinitionValidationException("Could not find unique destroy method on bean with name '" +
this.beanName + ": " + ex.getMessage());
}
}
4. findDestroyMethod
@Nullable
private Method findDestroyMethod(String name) {
// 如果允许访问非public方法,则从declareMethods中查找
// 否则,只从methods中查找
return (this.nonPublicAccessAllowed ?
BeanUtils.findMethodWithMinimalParameters(this.bean.getClass(), name) :
BeanUtils.findMethodWithMinimalParameters(this.bean.getClass().getMethods(), name));
}
这里的逻辑比较简单,如果允许访问非public方法:
- 先从
clazz.getMethods()
查找 - 如果找不到,则从
clazz.getDeclareMethods()
中查找 - 如果还是查找不到,获取父类,重复步骤1
如果不允许访问非public方法,直接通过clazz.getMethods()
中查找
getMethods
和getDeclareMethods
的区别在于,getMethod
仅获取所有public
方法,包含继承的public
方法,getDeclareMethods
可以获取到类中声明的public
、private
、protected
和default
方法,但不包含继承的方法
5. findMethodWithMinimalParameters
@Nullable
public static Method findMethodWithMinimalParameters(Class<?> clazz, String methodName)
throws IllegalArgumentException {
// 找到符合methodName的method,且形参个数最少,最好是0
Method targetMethod = findMethodWithMinimalParameters(clazz.getMethods(), methodName);
if (targetMethod == null) {
// 如果找不到,则从clazz的declareMethod中查找
targetMethod = findDeclaredMethodWithMinimalParameters(clazz, methodName);
}
return targetMethod;
}
6. findMethodWithMinimalParameters
@Nullable
public static Method findMethodWithMinimalParameters(Method[] methods, String methodName)
throws IllegalArgumentException {
Method targetMethod = null;
int numMethodsFoundWithCurrentMinimumArgs = 0;
for (Method method : methods) {
if (method.getName().equals(methodName)) {
int numParams = method.getParameterCount();
// 如果targetMethod为空(for循环第一次进来)
// 或者method的形参个数比targetMethod的形参个数少
// 意味着targetMethod是我们想找的方法
if (targetMethod == null || numParams < targetMethod.getParameterCount()) {
targetMethod = method;
numMethodsFoundWithCurrentMinimumArgs = 1;
}
else if (!method.isBridge() && targetMethod.getParameterCount() == numParams) {
// 如果之前找到的targetMethod是桥接方法,且进入这一分支意味着method不是桥接方法
// 那么替换targetMethod
if (targetMethod.isBridge()) {
// Prefer regular method over bridge...
targetMethod = method;
}
else {
// Additional candidate with same length
// 找到多个候选值,计量器+1
numMethodsFoundWithCurrentMinimumArgs++;
}
}
}
}
// 候选值超过1个,抛出异常,只想要唯一一个
if (numMethodsFoundWithCurrentMinimumArgs > 1) {
throw new IllegalArgumentException("Cannot resolve method '" + methodName +
"' to a unique method. Attempted to resolve to overloaded method with " +
"the least number of parameters but there were " +
numMethodsFoundWithCurrentMinimumArgs + " candidates.");
}
return targetMethod;
}
7. findDeclaredMethodWithMinimalParameters
@Nullable
public static Method findDeclaredMethodWithMinimalParameters(Class<?> clazz, String methodName)
throws IllegalArgumentException {
// 从declareMethod中查找符合methodName的method,且形参个数最少吗,最好是0
Method targetMethod = findMethodWithMinimalParameters(clazz.getDeclaredMethods(), methodName);
if (targetMethod == null && clazz.getSuperclass() != null) {
// 如果找不到,从父类递归本方法查找
targetMethod = findDeclaredMethodWithMinimalParameters(clazz.getSuperclass(), methodName);
}
return targetMethod;
}
8. getInterfaceMethodIfPossible
public static Method getInterfaceMethodIfPossible(Method method) {
// 如果不是public方法
// 或者method所属类本身就是一个interface
if (!Modifier.isPublic(method.getModifiers()) || method.getDeclaringClass().isInterface()) {
return method;
}
// 否则,从interfaceMethodCache获取,如果interfaceMethodCache不存在,则查找,并将结果写入interfaceMethodCache
return interfaceMethodCache.computeIfAbsent(method, key -> {
Class<?> current = key.getDeclaringClass();
while (current != null && current != Object.class) {
Class<?>[] ifcs = current.getInterfaces();
for (Class<?> ifc : ifcs) {
try {
return ifc.getMethod(key.getName(), key.getParameterTypes());
}
catch (NoSuchMethodException ex) {
// ignore
}
}
// 获取父类,继续循环
current = current.getSuperclass();
}
return key;
});
}
从method获取到接口层级的method,并进行缓存
9.filterPostProcessors
@Nullable
private List<DestructionAwareBeanPostProcessor> filterPostProcessors(List<BeanPostProcessor> processors, Object bean) {
List<DestructionAwareBeanPostProcessor> filteredPostProcessors = null;
if (!CollectionUtils.isEmpty(processors)) {
filteredPostProcessors = new ArrayList<>(processors.size());
for (BeanPostProcessor processor : processors) {
if (processor instanceof DestructionAwareBeanPostProcessor) {
DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
if (dabpp.requiresDestruction(bean)) {
filteredPostProcessors.add(dabpp);
}
}
}
}
return filteredPostProcessors;
}
遍历processors,如果是DestructionAwareBeanPostProcessor
类型,通过requiresDestruction
判断是否要求进行销毁:
default boolean requiresDestruction(Object bean) {
return true;
}
requiresDestruction
交由具体的DestructionAwareBeanPostProcessor
子类去实现
总结
DisposableBeanAdapter总体流程比较清晰,代码浅显易懂,最后通过一个流程图来总结并巩固一下记忆:
DisposableBeanAdapter
网友评论