diff --git a/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/consumer/MeshMQPushConsumer.java b/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/consumer/MeshMQPushConsumer.java index 4ac1edbfc8..998fcc1f08 100644 --- a/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/consumer/MeshMQPushConsumer.java +++ b/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/consumer/MeshMQPushConsumer.java @@ -27,7 +27,7 @@ import org.apache.eventmesh.api.AbstractContext; import org.apache.eventmesh.spi.EventMeshSPI; -@EventMeshSPI +@EventMeshSPI(isSingleton = false) public interface MeshMQPushConsumer extends Consumer { void init(Properties keyValue) throws Exception; diff --git a/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/producer/MeshMQProducer.java b/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/producer/MeshMQProducer.java index c717385e05..93fd3d30fb 100644 --- a/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/producer/MeshMQProducer.java +++ b/eventmesh-connector-api/src/main/java/org/apache/eventmesh/api/producer/MeshMQProducer.java @@ -26,7 +26,7 @@ import org.apache.eventmesh.api.RRCallback; import org.apache.eventmesh.spi.EventMeshSPI; -@EventMeshSPI +@EventMeshSPI(isSingleton = false) public interface MeshMQProducer extends Producer { void init(Properties properties) throws Exception; diff --git a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionLoader.java b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionLoader.java index 89696e04da..9531bc9ac1 100644 --- a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionLoader.java +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshExtensionLoader.java @@ -44,12 +44,18 @@ public static T getExtension(Class extensionType, String extensionName) { loadExtensionClass(extensionType); } if (!hasInitializeExtension(extensionName)) { - initializeExtension(extensionType, extensionName); + T instance = initializeExtension(extensionType, extensionName); + EventMeshSPI spiAnnotation = extensionType.getAnnotation(EventMeshSPI.class); + if (!spiAnnotation.isSingleton()) { + return instance; + } + EXTENSION_INSTANCE_CACHE.put(extensionName, instance); } return (T) EXTENSION_INSTANCE_CACHE.get(extensionName); } - private static void initializeExtension(Class extensionType, String extensionName) { + @SuppressWarnings("unchecked") + private static T initializeExtension(Class extensionType, String extensionName) { ConcurrentHashMap> extensionClassMap = EXTENSION_CLASS_LOAD_CACHE.get(extensionType); if (extensionClassMap == null) { throw new ExtensionException(String.format("Extension type:%s has not been loaded", extensionType)); @@ -61,7 +67,7 @@ private static void initializeExtension(Class extensionType, String exten try { Object extensionObj = aClass.newInstance(); logger.info("initialize extension instance success, extensionType: {}, extensionName: {}", extensionType, extensionName); - EXTENSION_INSTANCE_CACHE.put(extensionName, extensionObj); + return (T) extensionObj; } catch (InstantiationException | IllegalAccessException e) { throw new ExtensionException("Extension initialize error", e); } diff --git a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshSPI.java b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshSPI.java index 0ea72d431b..48b0ef076b 100644 --- a/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshSPI.java +++ b/eventmesh-spi/src/main/java/org/apache/eventmesh/spi/EventMeshSPI.java @@ -31,5 +31,10 @@ @Target({ElementType.TYPE}) public @interface EventMeshSPI { + /** + * If true, the spi instance is singleton + */ + boolean isSingleton() default false; + } diff --git a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/EventMeshExtensionFactoryTest.java b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/EventMeshExtensionFactoryTest.java index 649f4b18b2..dc75e24d81 100644 --- a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/EventMeshExtensionFactoryTest.java +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/EventMeshExtensionFactoryTest.java @@ -17,13 +17,24 @@ package org.apache.eventmesh.spi; +import org.apache.eventmesh.spi.example.TestPrototypeExtension; +import org.apache.eventmesh.spi.example.TestSingletonExtension; +import org.junit.Assert; import org.junit.Test; public class EventMeshExtensionFactoryTest { @Test - public void getExtension() { - TestExtension extensionA = EventMeshExtensionFactory.getExtension(TestExtension.class, "extensionA"); - extensionA.hello(); + public void testGetSingletonExtension() { + TestSingletonExtension extensionA = EventMeshExtensionFactory.getExtension(TestSingletonExtension.class, "singletonExtension"); + TestSingletonExtension extensionB = EventMeshExtensionFactory.getExtension(TestSingletonExtension.class, "singletonExtension"); + Assert.assertSame(extensionA, extensionB); + } + + @Test + public void testGetPrototypeExtension() { + TestPrototypeExtension prototypeExtensionA = EventMeshExtensionFactory.getExtension(TestPrototypeExtension.class, "prototypeExtension"); + TestPrototypeExtension prototypeExtensionB = EventMeshExtensionFactory.getExtension(TestPrototypeExtension.class, "prototypeExtension"); + Assert.assertNotSame(prototypeExtensionA, prototypeExtensionB); } } \ No newline at end of file diff --git a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/PrototypeExtension.java b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/PrototypeExtension.java new file mode 100644 index 0000000000..bcc82e10cf --- /dev/null +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/PrototypeExtension.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi.example; + +public class PrototypeExtension implements TestPrototypeExtension { + @Override + public void hello() { + System.out.println("I am PrototypeExtension"); + } +} diff --git a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/ExtensionA.java b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/SingletonExtension.java similarity index 83% rename from eventmesh-spi/src/test/java/org/apache/eventmesh/spi/ExtensionA.java rename to eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/SingletonExtension.java index 03513e6203..ca4a625d4b 100644 --- a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/ExtensionA.java +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/SingletonExtension.java @@ -15,12 +15,12 @@ * limitations under the License. */ -package org.apache.eventmesh.spi; +package org.apache.eventmesh.spi.example; -public class ExtensionA implements TestExtension { +public class SingletonExtension implements TestSingletonExtension { @Override public void hello() { - System.out.println("I am ExtensionA"); + System.out.println("I am SingletonExtension"); } } diff --git a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestPrototypeExtension.java b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestPrototypeExtension.java new file mode 100644 index 0000000000..0267c906a0 --- /dev/null +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestPrototypeExtension.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.eventmesh.spi.example; + +import org.apache.eventmesh.spi.EventMeshSPI; + +@EventMeshSPI(isSingleton = false) +public interface TestPrototypeExtension { + + void hello(); +} diff --git a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/TestExtension.java b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestSingletonExtension.java similarity index 83% rename from eventmesh-spi/src/test/java/org/apache/eventmesh/spi/TestExtension.java rename to eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestSingletonExtension.java index c0c9888130..11c61fe496 100644 --- a/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/TestExtension.java +++ b/eventmesh-spi/src/test/java/org/apache/eventmesh/spi/example/TestSingletonExtension.java @@ -15,10 +15,12 @@ * limitations under the License. */ -package org.apache.eventmesh.spi; +package org.apache.eventmesh.spi.example; -@EventMeshSPI -public interface TestExtension { +import org.apache.eventmesh.spi.EventMeshSPI; + +@EventMeshSPI(isSingleton = true) +public interface TestSingletonExtension { void hello(); } diff --git a/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.TestExtension b/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestPrototypeExtension similarity index 91% rename from eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.TestExtension rename to eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestPrototypeExtension index 3862ccbb4f..29764071d1 100644 --- a/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.TestExtension +++ b/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestPrototypeExtension @@ -14,4 +14,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -extensionA=org.apache.eventmesh.spi.ExtensionA \ No newline at end of file +prototypeExtension=org.apache.eventmesh.spi.example.PrototypeExtension \ No newline at end of file diff --git a/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestSingletonExtension b/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestSingletonExtension new file mode 100644 index 0000000000..af6c8b8970 --- /dev/null +++ b/eventmesh-spi/src/test/resources/META-INF/eventmesh/org.apache.eventmesh.spi.example.TestSingletonExtension @@ -0,0 +1,17 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +singletonExtension=org.apache.eventmesh.spi.example.SingletonExtension \ No newline at end of file