This is an automated email from the ASF dual-hosted git repository.

xiaoyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 492977e91e [type:fix] fix SPI create non singleton objects in 
multi-threaded scenarios (#5713)
492977e91e is described below

commit 492977e91ee07e26b6d305a9e51284a0fbc21c09
Author: eye-gu <[email protected]>
AuthorDate: Fri Oct 18 17:17:33 2024 +0800

    [type:fix] fix SPI create non singleton objects in multi-threaded scenarios 
(#5713)
    
    Co-authored-by: zhengpeng <[email protected]>
---
 .../org/apache/shenyu/spi/ExtensionLoader.java     | 75 +++++++++-------------
 1 file changed, 31 insertions(+), 44 deletions(-)

diff --git 
a/shenyu-spi/src/main/java/org/apache/shenyu/spi/ExtensionLoader.java 
b/shenyu-spi/src/main/java/org/apache/shenyu/spi/ExtensionLoader.java
index efb4e721ac..706187fb1d 100644
--- a/shenyu-spi/src/main/java/org/apache/shenyu/spi/ExtensionLoader.java
+++ b/shenyu-spi/src/main/java/org/apache/shenyu/spi/ExtensionLoader.java
@@ -51,6 +51,10 @@ public final class ExtensionLoader<T> {
     private static final String SHENYU_DIRECTORY = "META-INF/shenyu/";
     
     private static final Map<Class<?>, ExtensionLoader<?>> LOADERS = new 
ConcurrentHashMap<>();
+
+    private static final Comparator<Holder<Object>> HOLDER_COMPARATOR = 
Comparator.comparing(Holder::getOrder);
+
+    private static final Comparator<ClassEntity> CLASS_ENTITY_COMPARATOR = 
Comparator.comparing(ClassEntity::getOrder);
     
     private final Class<T> clazz;
     
@@ -64,10 +68,6 @@ public final class ExtensionLoader<T> {
     
     private String cachedDefaultName;
     
-    private final Comparator<Holder<Object>> holderComparator = 
Comparator.comparing(Holder::getOrder);
-    
-    private final Comparator<ClassEntity> classEntityComparator = 
Comparator.comparing(ClassEntity::getOrder);
-    
     /**
      * Instantiates a new Extension loader.
      *
@@ -141,6 +141,13 @@ public final class ExtensionLoader<T> {
         if (StringUtils.isBlank(name)) {
             throw new NullPointerException("get join name is null");
         }
+        ClassEntity classEntity = getExtensionClassesEntity().get(name);
+        if (Objects.isNull(classEntity)) {
+            throw new IllegalArgumentException(name + " name is error");
+        }
+        if (!classEntity.isSingleton()) {
+            return (T) createExtension(classEntity);
+        }
         Holder<Object> objectHolder = cachedInstances.get(name);
         if (Objects.isNull(objectHolder)) {
             cachedInstances.putIfAbsent(name, new Holder<>());
@@ -148,15 +155,11 @@ public final class ExtensionLoader<T> {
         }
         Object value = objectHolder.getValue();
         if (Objects.isNull(value)) {
-            synchronized (cachedInstances) {
+            synchronized (objectHolder) {
                 value = objectHolder.getValue();
                 if (Objects.isNull(value)) {
                     createExtension(name, objectHolder);
                     value = objectHolder.getValue();
-                    if (!objectHolder.isSingleton()) {
-                        Holder<Object> removeObj = 
cachedInstances.remove(name);
-                        removeObj = null;
-                    }
                 }
             }
         }
@@ -175,20 +178,32 @@ public final class ExtensionLoader<T> {
         }
         if (Objects.equals(extensionClassesEntity.size(), 
cachedInstances.size())) {
             return (List<T>) this.cachedInstances.values().stream()
-                    .sorted(holderComparator)
+                    .sorted(HOLDER_COMPARATOR)
                     .map(e -> {
                         return e.getValue();
                     }).collect(Collectors.toList());
         }
         List<T> joins = new ArrayList<>();
         List<ClassEntity> classEntities = 
extensionClassesEntity.values().stream()
-                .sorted(classEntityComparator).collect(Collectors.toList());
+                .sorted(CLASS_ENTITY_COMPARATOR).collect(Collectors.toList());
         classEntities.forEach(v -> {
             T join = this.getJoin(v.getName());
             joins.add(join);
         });
         return joins;
     }
+
+    @SuppressWarnings("unchecked")
+    private Object createExtension(final ClassEntity classEntity) {
+        Class<?> aClass = classEntity.getClazz();
+        try {
+            return aClass.newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new IllegalStateException("Extension instance(name: " + 
classEntity.getName() + ", class: "
+                    + aClass + ")  could not be instantiated: " + 
e.getMessage(), e);
+
+        }
+    }
     
     @SuppressWarnings("unchecked")
     private void createExtension(final String name, final Holder<Object> 
holder) {
@@ -199,22 +214,14 @@ public final class ExtensionLoader<T> {
         Class<?> aClass = classEntity.getClazz();
         Object o = joinInstances.get(aClass);
         if (Objects.isNull(o)) {
-            try {
-                if (classEntity.isSingleton()) {
-                    joinInstances.putIfAbsent(aClass, aClass.newInstance());
-                    o = joinInstances.get(aClass);
-                } else {
-                    o = aClass.newInstance();
-                }
-            } catch (InstantiationException | IllegalAccessException e) {
-                throw new IllegalStateException("Extension instance(name: " + 
name + ", class: "
-                        + aClass + ")  could not be instantiated: " + 
e.getMessage(), e);
-                
+            o = createExtension(classEntity);
+            if (classEntity.isSingleton()) {
+                joinInstances.putIfAbsent(aClass, o);
+                o = joinInstances.get(aClass);
             }
         }
         holder.setOrder(classEntity.getOrder());
         holder.setValue(o);
-        holder.setSingleton(classEntity.isSingleton());
     }
     
     /**
@@ -324,9 +331,7 @@ public final class ExtensionLoader<T> {
         private volatile T value;
         
         private Integer order;
-        
-        private boolean isSingleton;
-        
+
         /**
          * Gets value.
          *
@@ -362,24 +367,6 @@ public final class ExtensionLoader<T> {
         public Integer getOrder() {
             return order;
         }
-        
-        /**
-         * Is it a singleton object.
-         *
-         * @return true or false.
-         */
-        public boolean isSingleton() {
-            return isSingleton;
-        }
-        
-        /**
-         * Is it a singleton object.
-         *
-         * @param singleton true or false.
-         */
-        public void setSingleton(final boolean singleton) {
-            isSingleton = singleton;
-        }
     }
     
     private static final class ClassEntity {

Reply via email to