|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2024 the original author or authors. |
| 2 | + * Copyright 2002-2025 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
@@ -133,6 +133,9 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
133 | 133 | /** Spring ConversionService to use instead of PropertyEditors. */
|
134 | 134 | private @Nullable ConversionService conversionService;
|
135 | 135 |
|
| 136 | + /** Default PropertyEditorRegistrars to apply to the beans of this factory. */ |
| 137 | + private final Set<PropertyEditorRegistrar> defaultEditorRegistrars = new LinkedHashSet<>(4); |
| 138 | + |
136 | 139 | /** Custom PropertyEditorRegistrars to apply to the beans of this factory. */
|
137 | 140 | private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);
|
138 | 141 |
|
@@ -870,7 +873,12 @@ public void setConversionService(@Nullable ConversionService conversionService)
|
870 | 873 | @Override
|
871 | 874 | public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {
|
872 | 875 | Assert.notNull(registrar, "PropertyEditorRegistrar must not be null");
|
873 |
| - this.propertyEditorRegistrars.add(registrar); |
| 876 | + if (registrar.overridesDefaultEditors()) { |
| 877 | + this.defaultEditorRegistrars.add(registrar); |
| 878 | + } |
| 879 | + else { |
| 880 | + this.propertyEditorRegistrars.add(registrar); |
| 881 | + } |
874 | 882 | }
|
875 | 883 |
|
876 | 884 | /**
|
@@ -1098,6 +1106,7 @@ public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
|
1098 | 1106 | setBeanExpressionResolver(otherFactory.getBeanExpressionResolver());
|
1099 | 1107 | setConversionService(otherFactory.getConversionService());
|
1100 | 1108 | if (otherFactory instanceof AbstractBeanFactory otherAbstractFactory) {
|
| 1109 | + this.defaultEditorRegistrars.addAll(otherAbstractFactory.defaultEditorRegistrars); |
1101 | 1110 | this.propertyEditorRegistrars.addAll(otherAbstractFactory.propertyEditorRegistrars);
|
1102 | 1111 | this.customEditors.putAll(otherAbstractFactory.customEditors);
|
1103 | 1112 | this.typeConverter = otherAbstractFactory.typeConverter;
|
@@ -1297,36 +1306,48 @@ protected void initBeanWrapper(BeanWrapper bw) {
|
1297 | 1306 | protected void registerCustomEditors(PropertyEditorRegistry registry) {
|
1298 | 1307 | if (registry instanceof PropertyEditorRegistrySupport registrySupport) {
|
1299 | 1308 | registrySupport.useConfigValueEditors();
|
| 1309 | + if (!this.defaultEditorRegistrars.isEmpty()) { |
| 1310 | + // Optimization: lazy overriding of default editors only when needed |
| 1311 | + registrySupport.setDefaultEditorRegistrar(new BeanFactoryDefaultEditorRegistrar()); |
| 1312 | + } |
| 1313 | + } |
| 1314 | + else if (!this.defaultEditorRegistrars.isEmpty()) { |
| 1315 | + // Fallback: proactive overriding of default editors |
| 1316 | + applyEditorRegistrars(registry, this.defaultEditorRegistrars); |
1300 | 1317 | }
|
| 1318 | + |
1301 | 1319 | if (!this.propertyEditorRegistrars.isEmpty()) {
|
1302 |
| - for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) { |
1303 |
| - try { |
1304 |
| - registrar.registerCustomEditors(registry); |
1305 |
| - } |
1306 |
| - catch (BeanCreationException ex) { |
1307 |
| - Throwable rootCause = ex.getMostSpecificCause(); |
1308 |
| - if (rootCause instanceof BeanCurrentlyInCreationException bce) { |
1309 |
| - String bceBeanName = bce.getBeanName(); |
1310 |
| - if (bceBeanName != null && isCurrentlyInCreation(bceBeanName)) { |
1311 |
| - if (logger.isDebugEnabled()) { |
1312 |
| - logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() + |
1313 |
| - "] failed because it tried to obtain currently created bean '" + |
1314 |
| - ex.getBeanName() + "': " + ex.getMessage()); |
1315 |
| - } |
1316 |
| - onSuppressedException(ex); |
1317 |
| - continue; |
1318 |
| - } |
1319 |
| - } |
1320 |
| - throw ex; |
1321 |
| - } |
1322 |
| - } |
| 1320 | + applyEditorRegistrars(registry, this.propertyEditorRegistrars); |
1323 | 1321 | }
|
1324 | 1322 | if (!this.customEditors.isEmpty()) {
|
1325 | 1323 | this.customEditors.forEach((requiredType, editorClass) ->
|
1326 | 1324 | registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));
|
1327 | 1325 | }
|
1328 | 1326 | }
|
1329 | 1327 |
|
| 1328 | + private void applyEditorRegistrars(PropertyEditorRegistry registry, Set<PropertyEditorRegistrar> registrars) { |
| 1329 | + for (PropertyEditorRegistrar registrar : registrars) { |
| 1330 | + try { |
| 1331 | + registrar.registerCustomEditors(registry); |
| 1332 | + } |
| 1333 | + catch (BeanCreationException ex) { |
| 1334 | + Throwable rootCause = ex.getMostSpecificCause(); |
| 1335 | + if (rootCause instanceof BeanCurrentlyInCreationException bce) { |
| 1336 | + String bceBeanName = bce.getBeanName(); |
| 1337 | + if (bceBeanName != null && isCurrentlyInCreation(bceBeanName)) { |
| 1338 | + if (logger.isDebugEnabled()) { |
| 1339 | + logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() + |
| 1340 | + "] failed because it tried to obtain currently created bean '" + |
| 1341 | + ex.getBeanName() + "': " + ex.getMessage()); |
| 1342 | + } |
| 1343 | + onSuppressedException(ex); |
| 1344 | + return; |
| 1345 | + } |
| 1346 | + } |
| 1347 | + throw ex; |
| 1348 | + } |
| 1349 | + } |
| 1350 | + } |
1330 | 1351 |
|
1331 | 1352 | /**
|
1332 | 1353 | * Return a merged RootBeanDefinition, traversing the parent bean definition
|
@@ -2075,4 +2096,20 @@ static class BeanPostProcessorCache {
|
2075 | 2096 | final List<MergedBeanDefinitionPostProcessor> mergedDefinition = new ArrayList<>();
|
2076 | 2097 | }
|
2077 | 2098 |
|
| 2099 | + |
| 2100 | + /** |
| 2101 | + * {@link PropertyEditorRegistrar} that delegates to the bean factory's |
| 2102 | + * default registrars, adding exception handling for circular reference |
| 2103 | + * scenarios where an editor tries to refer back to the currently created bean. |
| 2104 | + * |
| 2105 | + * @since 6.2.3 |
| 2106 | + */ |
| 2107 | + class BeanFactoryDefaultEditorRegistrar implements PropertyEditorRegistrar { |
| 2108 | + |
| 2109 | + @Override |
| 2110 | + public void registerCustomEditors(PropertyEditorRegistry registry) { |
| 2111 | + applyEditorRegistrars(registry, defaultEditorRegistrars); |
| 2112 | + } |
| 2113 | + } |
| 2114 | + |
2078 | 2115 | }
|
0 commit comments