You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/10/24 11:02:45 UTC

[camel] 01/02: Bean cache (#11758)

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

davsclaus pushed a commit to branch camel-4.0.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit cc5dd3ebbe4908337648ae02d78d5c974df87ce9
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Oct 18 15:16:29 2023 +0200

    Bean cache (#11758)
    
    CAMEL-19999: camel-bean - Allow to configure bean introspection cache on component
---
 .../org/apache/camel/catalog/components/bean.json  |  3 +-
 .../org/apache/camel/catalog/components/class.json |  3 +-
 .../component/bean/BeanComponentConfigurer.java    |  6 ++++
 .../org/apache/camel/component/bean/bean.json      |  3 +-
 .../apache/camel/component/beanclass/class.json    |  3 +-
 .../apache/camel/component/bean/BeanComponent.java | 38 +++++++++++++++++++---
 .../component/dsl/BeanComponentBuilderFactory.java | 17 ++++++++++
 .../component/dsl/ClasComponentBuilderFactory.java | 17 ++++++++++
 8 files changed, 82 insertions(+), 8 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/bean.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/bean.json
index 7838e7fa650..55e0701a93f 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/bean.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/bean.json
@@ -24,7 +24,8 @@
   "componentProperties": {
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail [...]
     "scope": { "index": 1, "kind": "property", "displayName": "Scope", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "org.apache.camel.BeanScope", "enum": [ "Singleton", "Request", "Prototype" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "Singleton", "description": "Scope of bean. When using singleton scope (default) the bean is created or looked up only once and reused for the lifetime of the endpoint. The bean should  [...]
-    "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
+    "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
+    "beanInfoCacheSize": { "index": 3, "kind": "property", "displayName": "Bean Info Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 1000, "description": "Maximum cache size of internal cache for bean introspection. Setting a value of 0 or negative will disable the cache." }
   },
   "headers": {
     "CamelBeanMethodName": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The name of the method to invoke.", "constantName": "org.apache.camel.component.bean.BeanConstants#BEAN_METHOD_NAME" }
diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/class.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/class.json
index 8c591e51fee..deda411b044 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/class.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/class.json
@@ -24,7 +24,8 @@
   "componentProperties": {
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail [...]
     "scope": { "index": 1, "kind": "property", "displayName": "Scope", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "org.apache.camel.BeanScope", "enum": [ "Singleton", "Request", "Prototype" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "Singleton", "description": "Scope of bean. When using singleton scope (default) the bean is created or looked up only once and reused for the lifetime of the endpoint. The bean should  [...]
-    "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
+    "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
+    "beanInfoCacheSize": { "index": 3, "kind": "property", "displayName": "Bean Info Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 1000, "description": "Maximum cache size of internal cache for bean introspection. Setting a value of 0 or negative will disable the cache." }
   },
   "headers": {
     "CamelBeanMethodName": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The name of the method to invoke.", "constantName": "org.apache.camel.component.bean.BeanConstants#BEAN_METHOD_NAME" }
diff --git a/components/camel-bean/src/generated/java/org/apache/camel/component/bean/BeanComponentConfigurer.java b/components/camel-bean/src/generated/java/org/apache/camel/component/bean/BeanComponentConfigurer.java
index d508722a03d..5a94083acf0 100644
--- a/components/camel-bean/src/generated/java/org/apache/camel/component/bean/BeanComponentConfigurer.java
+++ b/components/camel-bean/src/generated/java/org/apache/camel/component/bean/BeanComponentConfigurer.java
@@ -23,6 +23,8 @@ public class BeanComponentConfigurer extends PropertyConfigurerSupport implement
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "autowiredenabled":
         case "autowiredEnabled": target.setAutowiredEnabled(property(camelContext, boolean.class, value)); return true;
+        case "beaninfocachesize":
+        case "beanInfoCacheSize": target.setBeanInfoCacheSize(property(camelContext, int.class, value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": target.setLazyStartProducer(property(camelContext, boolean.class, value)); return true;
         case "scope": target.setScope(property(camelContext, org.apache.camel.BeanScope.class, value)); return true;
@@ -35,6 +37,8 @@ public class BeanComponentConfigurer extends PropertyConfigurerSupport implement
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "autowiredenabled":
         case "autowiredEnabled": return boolean.class;
+        case "beaninfocachesize":
+        case "beanInfoCacheSize": return int.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
         case "scope": return org.apache.camel.BeanScope.class;
@@ -48,6 +52,8 @@ public class BeanComponentConfigurer extends PropertyConfigurerSupport implement
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "autowiredenabled":
         case "autowiredEnabled": return target.isAutowiredEnabled();
+        case "beaninfocachesize":
+        case "beanInfoCacheSize": return target.getBeanInfoCacheSize();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
         case "scope": return target.getScope();
diff --git a/components/camel-bean/src/generated/resources/org/apache/camel/component/bean/bean.json b/components/camel-bean/src/generated/resources/org/apache/camel/component/bean/bean.json
index 7838e7fa650..55e0701a93f 100644
--- a/components/camel-bean/src/generated/resources/org/apache/camel/component/bean/bean.json
+++ b/components/camel-bean/src/generated/resources/org/apache/camel/component/bean/bean.json
@@ -24,7 +24,8 @@
   "componentProperties": {
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail [...]
     "scope": { "index": 1, "kind": "property", "displayName": "Scope", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "org.apache.camel.BeanScope", "enum": [ "Singleton", "Request", "Prototype" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "Singleton", "description": "Scope of bean. When using singleton scope (default) the bean is created or looked up only once and reused for the lifetime of the endpoint. The bean should  [...]
-    "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
+    "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
+    "beanInfoCacheSize": { "index": 3, "kind": "property", "displayName": "Bean Info Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 1000, "description": "Maximum cache size of internal cache for bean introspection. Setting a value of 0 or negative will disable the cache." }
   },
   "headers": {
     "CamelBeanMethodName": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The name of the method to invoke.", "constantName": "org.apache.camel.component.bean.BeanConstants#BEAN_METHOD_NAME" }
diff --git a/components/camel-bean/src/generated/resources/org/apache/camel/component/beanclass/class.json b/components/camel-bean/src/generated/resources/org/apache/camel/component/beanclass/class.json
index 8c591e51fee..deda411b044 100644
--- a/components/camel-bean/src/generated/resources/org/apache/camel/component/beanclass/class.json
+++ b/components/camel-bean/src/generated/resources/org/apache/camel/component/beanclass/class.json
@@ -24,7 +24,8 @@
   "componentProperties": {
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail [...]
     "scope": { "index": 1, "kind": "property", "displayName": "Scope", "group": "producer", "label": "", "required": false, "type": "object", "javaType": "org.apache.camel.BeanScope", "enum": [ "Singleton", "Request", "Prototype" ], "deprecated": false, "autowired": false, "secret": false, "defaultValue": "Singleton", "description": "Scope of bean. When using singleton scope (default) the bean is created or looked up only once and reused for the lifetime of the endpoint. The bean should  [...]
-    "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
+    "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
+    "beanInfoCacheSize": { "index": 3, "kind": "property", "displayName": "Bean Info Cache Size", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 1000, "description": "Maximum cache size of internal cache for bean introspection. Setting a value of 0 or negative will disable the cache." }
   },
   "headers": {
     "CamelBeanMethodName": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The name of the method to invoke.", "constantName": "org.apache.camel.component.bean.BeanConstants#BEAN_METHOD_NAME" }
diff --git a/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanComponent.java b/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanComponent.java
index 7381aa92c30..7fb4a8f1e54 100644
--- a/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanComponent.java
+++ b/components/camel-bean/src/main/java/org/apache/camel/component/bean/BeanComponent.java
@@ -38,7 +38,7 @@ public class BeanComponent extends DefaultComponent {
 
     // use an internal soft cache for BeanInfo as they are costly to introspect
     // for example the bean language using OGNL expression runs much faster reusing the BeanInfo from this cache
-    private final Map<BeanInfoCacheKey, BeanInfo> beanInfoCache = LRUCacheFactory.newLRUSoftCache(1000);
+    private Map<BeanInfoCacheKey, BeanInfo> beanInfoCache;
 
     @Metadata(defaultValue = "Singleton", description = "Scope of bean."
                                                         + " When using singleton scope (default) the bean is created or looked up only once and reused for the lifetime of the endpoint."
@@ -51,9 +51,23 @@ public class BeanComponent extends DefaultComponent {
                                                         + " so when using prototype then this depends on the delegated registry.")
     private BeanScope scope = BeanScope.Singleton;
 
+    @Metadata(label = "advanced", defaultValue = "1000",
+              description = "Maximum cache size of internal cache for bean introspection. Setting a value of 0 or negative will disable the cache.")
+    private int beanInfoCacheSize = 1000;
+
     public BeanComponent() {
     }
 
+    @Override
+    protected void doInit() throws Exception {
+        super.doInit();
+
+        if (beanInfoCache == null && beanInfoCacheSize > 0) {
+            LOG.debug("Creating BeanInfo with maximum cache size: {}", beanInfoCacheSize);
+            beanInfoCache = LRUCacheFactory.newLRUSoftCache(beanInfoCacheSize);
+        }
+    }
+
     // Implementation methods
     //-----------------------------------------------------------------------
     @Override
@@ -70,11 +84,17 @@ public class BeanComponent extends DefaultComponent {
     }
 
     BeanInfo getBeanInfoFromCache(BeanInfoCacheKey key) {
-        return beanInfoCache.get(key);
+        if (beanInfoCache != null) {
+            return beanInfoCache.get(key);
+        } else {
+            return null;
+        }
     }
 
     void addBeanInfoToCache(BeanInfoCacheKey key, BeanInfo beanInfo) {
-        beanInfoCache.put(key, beanInfo);
+        if (beanInfoCache != null) {
+            beanInfoCache.put(key, beanInfo);
+        }
     }
 
     @Override
@@ -83,7 +103,9 @@ public class BeanComponent extends DefaultComponent {
             LOG.debug("Clearing BeanInfo cache[size={}, hits={}, misses={}, evicted={}]", cache.size(), cache.getHits(),
                     cache.getMisses(), cache.getEvicted());
         }
-        beanInfoCache.clear();
+        if (beanInfoCache != null) {
+            beanInfoCache.clear();
+        }
     }
 
     public BeanScope getScope() {
@@ -93,4 +115,12 @@ public class BeanComponent extends DefaultComponent {
     public void setScope(BeanScope scope) {
         this.scope = scope;
     }
+
+    public int getBeanInfoCacheSize() {
+        return beanInfoCacheSize;
+    }
+
+    public void setBeanInfoCacheSize(int beanInfoCacheSize) {
+        this.beanInfoCacheSize = beanInfoCacheSize;
+    }
 }
diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/BeanComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/BeanComponentBuilderFactory.java
index f3e3faa609b..bf436a19e0a 100644
--- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/BeanComponentBuilderFactory.java
+++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/BeanComponentBuilderFactory.java
@@ -120,6 +120,22 @@ public interface BeanComponentBuilderFactory {
             doSetProperty("autowiredEnabled", autowiredEnabled);
             return this;
         }
+        /**
+         * Maximum cache size of internal cache for bean introspection. Setting
+         * a value of 0 or negative will disable the cache.
+         * 
+         * The option is a: &lt;code&gt;int&lt;/code&gt; type.
+         * 
+         * Default: 1000
+         * Group: advanced
+         * 
+         * @param beanInfoCacheSize the value to set
+         * @return the dsl builder
+         */
+        default BeanComponentBuilder beanInfoCacheSize(int beanInfoCacheSize) {
+            doSetProperty("beanInfoCacheSize", beanInfoCacheSize);
+            return this;
+        }
     }
 
     class BeanComponentBuilderImpl
@@ -140,6 +156,7 @@ public interface BeanComponentBuilderFactory {
             case "lazyStartProducer": ((BeanComponent) component).setLazyStartProducer((boolean) value); return true;
             case "scope": ((BeanComponent) component).setScope((org.apache.camel.BeanScope) value); return true;
             case "autowiredEnabled": ((BeanComponent) component).setAutowiredEnabled((boolean) value); return true;
+            case "beanInfoCacheSize": ((BeanComponent) component).setBeanInfoCacheSize((int) value); return true;
             default: return false;
             }
         }
diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ClasComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ClasComponentBuilderFactory.java
index 0713d7b5ac5..002a7f646ff 100644
--- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ClasComponentBuilderFactory.java
+++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/ClasComponentBuilderFactory.java
@@ -120,6 +120,22 @@ public interface ClasComponentBuilderFactory {
             doSetProperty("autowiredEnabled", autowiredEnabled);
             return this;
         }
+        /**
+         * Maximum cache size of internal cache for bean introspection. Setting
+         * a value of 0 or negative will disable the cache.
+         * 
+         * The option is a: &lt;code&gt;int&lt;/code&gt; type.
+         * 
+         * Default: 1000
+         * Group: advanced
+         * 
+         * @param beanInfoCacheSize the value to set
+         * @return the dsl builder
+         */
+        default ClasComponentBuilder beanInfoCacheSize(int beanInfoCacheSize) {
+            doSetProperty("beanInfoCacheSize", beanInfoCacheSize);
+            return this;
+        }
     }
 
     class ClasComponentBuilderImpl
@@ -140,6 +156,7 @@ public interface ClasComponentBuilderFactory {
             case "lazyStartProducer": ((ClassComponent) component).setLazyStartProducer((boolean) value); return true;
             case "scope": ((ClassComponent) component).setScope((org.apache.camel.BeanScope) value); return true;
             case "autowiredEnabled": ((ClassComponent) component).setAutowiredEnabled((boolean) value); return true;
+            case "beanInfoCacheSize": ((ClassComponent) component).setBeanInfoCacheSize((int) value); return true;
             default: return false;
             }
         }