Skip to content

Commit

Permalink
Improve startup performance
Browse files Browse the repository at this point in the history
  • Loading branch information
stephanpelikan committed Jan 29, 2024
1 parent 0da5cfe commit 9e72846
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 50 deletions.
52 changes: 52 additions & 0 deletions src/main/java/io/vanillabp/springboot/adapter/SpringBeanUtil.java
Original file line number Diff line number Diff line change
@@ -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<String, Object> workflowAnnotatedBeansCache;

private boolean cached = true;

public SpringBeanUtil(
final ApplicationContext applicationContext) {

this.applicationContext = applicationContext;

}

public Map<String, Object> 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;
}

}

}
25 changes: 12 additions & 13 deletions src/main/java/io/vanillabp/springboot/adapter/TaskHandlerBase.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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 {

Expand Down Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@ public abstract class TaskWiringBase<T extends Connectable, PS extends ProcessSe

public TaskWiringBase(
final ApplicationContext applicationContext,
final SpringBeanUtil springBeanUtil,
final M methodParameterFactory) {

super(applicationContext, methodParameterFactory);
super(applicationContext, springBeanUtil, methodParameterFactory);

}

@SuppressWarnings("unchecked")
public TaskWiringBase(
final ApplicationContext applicationContext) {

this(applicationContext, (M) new MethodParameterFactory());
final ApplicationContext applicationContext,
final SpringBeanUtil springBeanUtil) {

this(applicationContext, springBeanUtil, (M) new MethodParameterFactory());

}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,5 @@
package io.vanillabp.springboot.adapter.wiring;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.springframework.aop.support.AopUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import io.vanillabp.spi.service.BpmnProcess;
import io.vanillabp.spi.service.MultiInstanceElement;
import io.vanillabp.spi.service.MultiInstanceIndex;
Expand All @@ -26,22 +8,44 @@
import io.vanillabp.spi.service.TaskParam;
import io.vanillabp.spi.service.WorkflowService;
import io.vanillabp.springboot.adapter.Connectable;
import io.vanillabp.springboot.adapter.SpringBeanUtil;
import io.vanillabp.springboot.parameters.MethodParameter;
import io.vanillabp.springboot.parameters.MethodParameterFactory;
import io.vanillabp.springboot.utils.MutableStream;
import io.vanillabp.springboot.utils.TriFunction;
import org.springframework.aop.support.AopUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public abstract class AbstractTaskWiring<T extends Connectable, A extends Annotation, M extends MethodParameterFactory> {

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;

}
Expand All @@ -68,15 +72,15 @@ 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());
})
.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());
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -245,7 +249,7 @@ protected List<MethodParameter> validateParameters(
parameters
.getStream()
.forEach(param -> {
if (unknown.length() != 0) {
if (!unknown.isEmpty()) {
unknown.append(", ");
}
unknown.append(index.get());
Expand All @@ -256,7 +260,7 @@ protected List<MethodParameter> validateParameters(
unknown.append(")");
});

if (unknown.length() != 0) {
if (!unknown.isEmpty()) {
throw new RuntimeException(
"Unexpected parameter(s) in method '"
+ method.getName()
Expand Down Expand Up @@ -393,12 +397,12 @@ protected Map.Entry<Class<?>, 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());
Expand All @@ -410,7 +414,7 @@ protected Map.Entry<Class<?>, 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
Expand All @@ -425,15 +429,15 @@ protected Map.Entry<Class<?>, Class<?>> determineAndValidateWorkflowAggregateAnd
.entrySet()
.stream()
.peek(entry -> {
if (found.length() > 0) {
if (!found.isEmpty()) {
found.append("; ");
}
found.append(entry.getKey().getName());
found.append(" by ");
})
.flatMap(entry -> entry.getValue().stream())
.forEach(matchingService -> {
if (found.length() > 0) {
if (!found.isEmpty()) {
found.append(", ");
}
found.append(matchingService.getName());
Expand Down Expand Up @@ -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()
Expand Down

0 comments on commit 9e72846

Please sign in to comment.