diff --git a/src/main/java/io/vanillabp/springboot/adapter/SpringBeanUtil.java b/src/main/java/io/vanillabp/springboot/adapter/SpringBeanUtil.java new file mode 100644 index 0000000..f8d02c5 --- /dev/null +++ b/src/main/java/io/vanillabp/springboot/adapter/SpringBeanUtil.java @@ -0,0 +1,52 @@ +package io.vanillabp.springboot.adapter; + +import io.vanillabp.spi.service.WorkflowService; +import org.springframework.context.ApplicationContext; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.context.event.EventListener; + +import java.util.Map; + +public class SpringBeanUtil { + + private final ApplicationContext applicationContext; + + private Map workflowAnnotatedBeansCache; + + private boolean cached = true; + + public SpringBeanUtil( + final ApplicationContext applicationContext) { + + this.applicationContext = applicationContext; + + } + + public Map getWorkflowAnnotatedBeans() { + + synchronized (this) { + if (workflowAnnotatedBeansCache != null) { + return workflowAnnotatedBeansCache; + } + final var beans = applicationContext + .getBeansWithAnnotation(WorkflowService.class); + if (cached) { + workflowAnnotatedBeansCache = beans; + } + return beans; + } + + } + + @EventListener + void onApplicationEvent( + final ContextRefreshedEvent event) { + + synchronized (this) { + cached = false; // only cache during startup + workflowAnnotatedBeansCache = null; + } + + } + +} diff --git a/src/main/java/io/vanillabp/springboot/adapter/TaskHandlerBase.java b/src/main/java/io/vanillabp/springboot/adapter/TaskHandlerBase.java index 53c40fd..e78ed2f 100644 --- a/src/main/java/io/vanillabp/springboot/adapter/TaskHandlerBase.java +++ b/src/main/java/io/vanillabp/springboot/adapter/TaskHandlerBase.java @@ -1,17 +1,5 @@ package io.vanillabp.springboot.adapter; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.function.Supplier; - -import org.slf4j.Logger; -import org.springframework.data.repository.CrudRepository; - import io.vanillabp.spi.service.MultiInstanceElementResolver; import io.vanillabp.spi.service.TaskEvent; import io.vanillabp.springboot.adapter.wiring.WorkflowAggregateCache; @@ -25,6 +13,17 @@ import io.vanillabp.springboot.parameters.TaskParameter; import io.vanillabp.springboot.parameters.WorkflowAggregateMethodParameter; import io.vanillabp.springboot.utils.MutableStream; +import org.slf4j.Logger; +import org.springframework.data.repository.CrudRepository; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; public abstract class TaskHandlerBase { @@ -289,7 +288,7 @@ protected boolean processWorkflowAggregateParameter( // workflow aggregate is not possible. workflowAggregateCache.workflowAggregate = workflowAggregateRepository .findById(workflowAggregateId) - .get(); + .orElse(null); args[param.getIndex()] = workflowAggregateCache.workflowAggregate; diff --git a/src/main/java/io/vanillabp/springboot/adapter/TaskWiringBase.java b/src/main/java/io/vanillabp/springboot/adapter/TaskWiringBase.java index f2167c4..418a50b 100644 --- a/src/main/java/io/vanillabp/springboot/adapter/TaskWiringBase.java +++ b/src/main/java/io/vanillabp/springboot/adapter/TaskWiringBase.java @@ -18,17 +18,19 @@ public abstract class TaskWiringBase { protected final ApplicationContext applicationContext; - + + protected final SpringBeanUtil springBeanUtil; + protected final M methodParameterFactory; public AbstractTaskWiring( final ApplicationContext applicationContext, + final SpringBeanUtil springBeanUtil, final M methodParameterFactory) { this.applicationContext = applicationContext; + this.springBeanUtil = springBeanUtil; this.methodParameterFactory = methodParameterFactory; } @@ -68,7 +72,7 @@ private void connectConnectableToBean( .stream(method.getAnnotationsByType(getAnnotationType())) .map(annotation -> Map.entry(method, annotation))) .peek(m -> { - if (tested.length() > 0) { + if (!tested.isEmpty()) { tested.append(", "); } tested.append(m.getKey().toString()); @@ -76,7 +80,7 @@ private void connectConnectableToBean( .filter(m -> methodMatchesTaskDefinition.apply(m.getKey(), m.getValue()) || methodMatchesElementId.apply(m.getKey(), m.getValue())) .peek(m -> { - if (matching.length() > 0) { + if (!matching.isEmpty()) { matching.append(", "); } matching.append(m.getKey().toString()); @@ -111,9 +115,9 @@ protected boolean wireTask( final var tested = new StringBuilder(); final var matching = new StringBuilder(); final var matchingMethods = new AtomicInteger(0); - - applicationContext - .getBeansWithAnnotation(WorkflowService.class) + + springBeanUtil + .getWorkflowAnnotatedBeans() .entrySet() .stream() .filter(bean -> isAboutConnectableProcess( @@ -245,7 +249,7 @@ protected List validateParameters( parameters .getStream() .forEach(param -> { - if (unknown.length() != 0) { + if (!unknown.isEmpty()) { unknown.append(", "); } unknown.append(index.get()); @@ -256,7 +260,7 @@ protected List validateParameters( unknown.append(")"); }); - if (unknown.length() != 0) { + if (!unknown.isEmpty()) { throw new RuntimeException( "Unexpected parameter(s) in method '" + method.getName() @@ -393,12 +397,12 @@ protected Map.Entry, Class> determineAndValidateWorkflowAggregateAnd final var tested = new StringBuilder(); - final var matchingServices = applicationContext - .getBeansWithAnnotation(WorkflowService.class) + final var matchingServices = springBeanUtil + .getWorkflowAnnotatedBeans() .entrySet() .stream() .peek(bean -> { - if (tested.length() > 0) { + if (!tested.isEmpty()) { tested.append(", "); } tested.append(bean.getKey()); @@ -410,7 +414,7 @@ protected Map.Entry, Class> determineAndValidateWorkflowAggregateAnd Entry::getValue, Collectors.mapping(Entry::getKey, Collectors.toList()))); - if (matchingServices.size() == 0) { + if (matchingServices.isEmpty()) { throw new RuntimeException( "No bean annotated with @WorkflowService(bpmnProcessId=\"" + bpmnProcessId @@ -425,7 +429,7 @@ protected Map.Entry, Class> determineAndValidateWorkflowAggregateAnd .entrySet() .stream() .peek(entry -> { - if (found.length() > 0) { + if (!found.isEmpty()) { found.append("; "); } found.append(entry.getKey().getName()); @@ -433,7 +437,7 @@ protected Map.Entry, Class> determineAndValidateWorkflowAggregateAnd }) .flatMap(entry -> entry.getValue().stream()) .forEach(matchingService -> { - if (found.length() > 0) { + if (!found.isEmpty()) { found.append(", "); } found.append(matchingService.getName()); @@ -497,7 +501,7 @@ protected boolean isPrimaryProcessWiring( .map(bpmnProcess -> bpmnProcess.bpmnProcessId().equals(BpmnProcess.USE_CLASS_NAME) ? workflowServiceClass.getSimpleName() : bpmnProcess.bpmnProcessId()) - .collect(Collectors.toList()); + .toList(); if (primaryBpmnProcessIds.size() > 1) { final var bpmnProcessIds = primaryBpmnProcessIds .stream()