Skip to content

Commit e2336e0

Browse files
Update spring and remove @Inject where @bean is present (#1762) LMCROSSITXSADEPLOY-3375
LMCROSSITXSADEPLOY-3375
1 parent d064584 commit e2336e0

File tree

11 files changed

+69
-60
lines changed

11 files changed

+69
-60
lines changed

multiapps-controller-core/src/main/java/org/cloudfoundry/multiapps/controller/core/auditlogging/AuditLogBean.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import javax.sql.DataSource;
44

5-
import jakarta.inject.Inject;
65
import org.cloudfoundry.multiapps.controller.core.auditlogging.impl.AuditLoggingFacadeSLImpl;
76
import org.springframework.context.annotation.Bean;
87
import org.springframework.context.annotation.Configuration;
@@ -11,61 +10,51 @@
1110
public class AuditLogBean {
1211

1312
@Bean
14-
@Inject
1513
public AuditLoggingFacade buildAuditLoggingFacade(DataSource dataSource, UserInfoProvider userInfoProvider) {
1614
return new AuditLoggingFacadeSLImpl(dataSource, userInfoProvider);
1715
}
1816

1917
@Bean
20-
@Inject
2118
public CsrfTokenApiServiceAuditLog buildCsrfTokenApiServiceAuditLog(AuditLoggingFacade auditLoggingFacade) {
2219
return new CsrfTokenApiServiceAuditLog(auditLoggingFacade);
2320
}
2421

2522
@Bean
26-
@Inject
2723
public FilesApiServiceAuditLog buildFilesApiServiceAuditLog(AuditLoggingFacade auditLoggingFacade) {
2824
return new FilesApiServiceAuditLog(auditLoggingFacade);
2925
}
3026

3127
@Bean
32-
@Inject
3328
public LoginAttemptAuditLog buildLoginAttemptAuditLog(AuditLoggingFacade auditLoggingFacade) {
3429
return new LoginAttemptAuditLog(auditLoggingFacade);
3530
}
3631

3732
@Bean
38-
@Inject
3933
public InfoApiServiceAuditLog buildInfoApiServiceAuditLog(AuditLoggingFacade auditLoggingFacade) {
4034
return new InfoApiServiceAuditLog(auditLoggingFacade);
4135
}
4236

4337
@Bean
44-
@Inject
4538
public MtasApiServiceAuditLog buildMtasApiServiceAuditLog(AuditLoggingFacade auditLoggingFacade) {
4639
return new MtasApiServiceAuditLog(auditLoggingFacade);
4740
}
4841

4942
@Bean
50-
@Inject
5143
public OperationsApiServiceAuditLog buildOperationsApiServiceAuditLog(AuditLoggingFacade auditLoggingFacade) {
5244
return new OperationsApiServiceAuditLog(auditLoggingFacade);
5345
}
5446

5547
@Bean
56-
@Inject
5748
public MtaConfigurationPurgerAuditLog buildMtaConfigurationPurgerAuditLog(AuditLoggingFacade auditLoggingFacade) {
5849
return new MtaConfigurationPurgerAuditLog(auditLoggingFacade);
5950
}
6051

6152
@Bean
62-
@Inject
6353
public ConfigurationSubscriptionServiceAuditLog buildAConfigurationSubscriptionServiceAuditLog(AuditLoggingFacade auditLoggingFacade) {
6454
return new ConfigurationSubscriptionServiceAuditLog(auditLoggingFacade);
6555
}
6656

6757
@Bean
68-
@Inject
6958
public ConfigurationEntryServiceAuditLog buildAConfigurationEntryServiceAuditLog(AuditLoggingFacade auditLoggingFacade) {
7059
return new ConfigurationEntryServiceAuditLog(auditLoggingFacade);
7160
}

multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/flowable/FlowableFacade.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,10 @@
3030
import org.flowable.variable.api.persistence.entity.VariableInstance;
3131
import org.slf4j.Logger;
3232
import org.slf4j.LoggerFactory;
33+
import org.springframework.context.annotation.DependsOn;
3334

3435
@Named
36+
@DependsOn("processEngine")
3537
public class FlowableFacade {
3638

3739
private static final Logger LOGGER = LoggerFactory.getLogger(FlowableFacade.class);

multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/jobs/LockOwnerReporter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
import org.flowable.engine.ProcessEngine;
1616
import org.slf4j.Logger;
1717
import org.slf4j.LoggerFactory;
18+
import org.springframework.context.annotation.DependsOn;
1819
import org.springframework.scheduling.annotation.Scheduled;
1920

2021
@Named
22+
@DependsOn("processEngine")
2123
public class LockOwnerReporter {
2224

2325
private static final Logger LOGGER = LoggerFactory.getLogger(LockOwnerReporter.class);

multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/util/LockOwnerReleaser.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
import org.flowable.engine.impl.cmd.ClearProcessInstanceLockTimesCmd;
1212
import org.flowable.job.api.Job;
1313
import org.flowable.job.service.JobServiceConfiguration;
14+
import org.springframework.context.annotation.DependsOn;
1415

1516
@Named("lockOwnerReleaser")
17+
@DependsOn("processEngine")
1618
public class LockOwnerReleaser {
1719

1820
private final ProcessEngine processEngine;

multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/configuration/DatabaseConfiguration.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import javax.sql.DataSource;
44

5-
import jakarta.inject.Inject;
65
import liquibase.integration.spring.SpringLiquibase;
76
import org.cloudfoundry.multiapps.controller.core.util.ApplicationConfiguration;
87
import org.cloudfoundry.multiapps.controller.persistence.DataSourceWithDialect;
@@ -26,7 +25,6 @@ public class DatabaseConfiguration {
2625
private static final String LIQUIBASE_CHANGELOG = "classpath:/org/cloudfoundry/multiapps/controller/persistence/db/changelog/db-changelog.xml";
2726
private static final String ENTITY_MANAGER_DEFAULT_PERSISTENCE_UNIT_NAME = "Default";
2827

29-
@Inject
3028
@Bean
3129
public CloudDataSourceFactoryBean dataSource(DataSourceFactory dataSourceFactory, EnvironmentServicesFinder vcapServiceFinder,
3230
ApplicationConfiguration configuration) {
@@ -38,13 +36,11 @@ public DefaultDataSourceDialect dataSourceDialect() {
3836
return new DefaultDataSourceDialect();
3937
}
4038

41-
@Inject
4239
@Bean
4340
public DataSourceWithDialect dataSourceWithDialect(DataSource dataSource, DataSourceDialect dataSourceDialect) {
4441
return new DataSourceWithDialect(dataSource, dataSourceDialect);
4542
}
4643

47-
@Inject
4844
@Bean
4945
public DataSourceTransactionManager transactionManager(DataSource dataSource, ApplicationConfiguration applicationConfiguration) {
5046
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
@@ -79,7 +75,6 @@ public EclipseLinkJpaVendorAdapter eclipseLinkJpaVendorAdapter() {
7975
return eclipseLinkJpaVendorAdapter;
8076
}
8177

82-
@Inject
8378
@Bean
8479
public SpringLiquibase liquibaseChangelog(DataSource dataSource) {
8580
return getLiquibaseTemplate(dataSource, LIQUIBASE_CHANGELOG);

multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/configuration/FlowableConfiguration.java

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,10 @@
55
import java.util.function.Supplier;
66
import javax.sql.DataSource;
77

8-
import jakarta.inject.Inject;
98
import org.cloudfoundry.multiapps.controller.core.util.ApplicationConfiguration;
109
import org.flowable.common.engine.impl.AbstractEngineConfiguration;
1110
import org.flowable.common.engine.impl.async.DefaultAsyncTaskExecutor;
1211
import org.flowable.common.engine.impl.persistence.StrongUuidGenerator;
13-
import org.flowable.engine.HistoryService;
14-
import org.flowable.engine.ProcessEngine;
15-
import org.flowable.engine.RuntimeService;
1612
import org.flowable.job.service.impl.asyncexecutor.AsyncExecutor;
1713
import org.flowable.job.service.impl.asyncexecutor.DefaultAsyncJobExecutor;
1814
import org.flowable.job.service.impl.asyncexecutor.FailedJobCommandFactory;
@@ -42,18 +38,28 @@ public class FlowableConfiguration {
4238
protected Supplier<String> randomIdGenerator = () -> UUID.randomUUID()
4339
.toString();
4440

45-
@Inject
41+
/**
42+
* Creates the ProcessEngine bean via ProcessEngineFactoryBean.
43+
*
44+
* Important: We return ProcessEngineFactoryBean (which implements FactoryBean<ProcessEngine>)
45+
* instead of calling getObject() directly. This allows Spring to properly manage the factory bean's
46+
* lifecycle and ensures the ProcessEngine is created at the correct time during context initialization.
47+
*
48+
* This approach resolves intermittent circular dependency issues that can occur with Spring 6.2.15+
49+
* when beans depending on ProcessEngine are initialized concurrently.
50+
*
51+
* @see FlowableServicesConfiguration for RuntimeService and HistoryService beans
52+
*/
4653
@Bean
4754
@DependsOn("liquibaseChangelog")
48-
public ProcessEngine processEngine(ApplicationContext applicationContext, SpringProcessEngineConfiguration processEngineConfiguration)
49-
throws Exception {
50-
ProcessEngineFactoryBean processEngineFactoryBean = new ProcessEngineFactoryBean();
51-
processEngineFactoryBean.setApplicationContext(applicationContext);
52-
processEngineFactoryBean.setProcessEngineConfiguration(processEngineConfiguration);
53-
return processEngineFactoryBean.getObject();
55+
public ProcessEngineFactoryBean processEngine(ApplicationContext applicationContext,
56+
SpringProcessEngineConfiguration processEngineConfiguration) {
57+
ProcessEngineFactoryBean factory = new ProcessEngineFactoryBean();
58+
factory.setApplicationContext(applicationContext);
59+
factory.setProcessEngineConfiguration(processEngineConfiguration);
60+
return factory;
5461
}
5562

56-
@Inject
5763
@Bean
5864
@DependsOn("liquibaseChangelog")
5965
public SpringProcessEngineConfiguration processEngineConfiguration(DataSource dataSource, PlatformTransactionManager transactionManager,
@@ -79,7 +85,6 @@ public SpringProcessEngineConfiguration processEngineConfiguration(DataSource da
7985
return processEngineConfiguration;
8086
}
8187

82-
@Inject
8388
@Bean
8489
public AsyncExecutor jobExecutor(DefaultAsyncTaskExecutor asyncTaskExecutor, String jobExecutorId) {
8590
DefaultAsyncJobExecutor jobExecutor = new DefaultAsyncJobExecutor() {
@@ -103,7 +108,6 @@ protected void initAsyncJobExecutionThreadPool() {
103108
return jobExecutor;
104109
}
105110

106-
@Inject
107111
@Bean
108112
public DefaultAsyncTaskExecutor taskExecutor(ApplicationConfiguration configuration) {
109113
DefaultAsyncTaskExecutor taskExecutor = new DefaultAsyncTaskExecutor();
@@ -114,7 +118,6 @@ public DefaultAsyncTaskExecutor taskExecutor(ApplicationConfiguration configurat
114118
return taskExecutor;
115119
}
116120

117-
@Inject
118121
@Bean
119122
public String jobExecutorId(ApplicationConfiguration applicationConfiguration) {
120123
String applicationGuid = applicationConfiguration.getApplicationGuid();
@@ -128,16 +131,4 @@ public String jobExecutorId(ApplicationConfiguration applicationConfiguration) {
128131
private String buildJobExecutorId(String applicationId, int applicationInstanceIndex) {
129132
return String.format(JOB_EXECUTOR_ID_TEMPLATE, applicationId, applicationInstanceIndex, randomIdGenerator.get());
130133
}
131-
132-
@Inject
133-
@Bean
134-
public RuntimeService runtimeService(ProcessEngine processEngine) {
135-
return processEngine.getRuntimeService();
136-
}
137-
138-
@Inject
139-
@Bean
140-
public HistoryService historyService(ProcessEngine processEngine) {
141-
return processEngine.getHistoryService();
142-
}
143134
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package org.cloudfoundry.multiapps.controller.web.configuration;
2+
3+
import org.flowable.engine.HistoryService;
4+
import org.flowable.engine.ProcessEngine;
5+
import org.flowable.engine.RuntimeService;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
import org.springframework.context.annotation.DependsOn;
9+
10+
/**
11+
* Configuration for Flowable engine service beans.
12+
*
13+
* These beans are extracted from FlowableConfiguration to ensure proper initialization order.
14+
* The @DependsOn("processEngine") ensures that the ProcessEngineFactoryBean is fully initialized
15+
* and the ProcessEngine is available before these service beans are created.
16+
*
17+
* Note: @Lazy is not used here because:
18+
* 1. The ProcessEngine is properly managed via ProcessEngineFactoryBean, which handles lifecycle correctly
19+
* 2. Components like FlowableHistoricDataCleaner need HistoryService at startup for scheduled jobs
20+
* 3. Using @Lazy could cause unexpected initialization timing issues
21+
*/
22+
@Configuration
23+
public class FlowableServicesConfiguration {
24+
25+
@Bean
26+
@DependsOn("processEngine")
27+
public RuntimeService runtimeService(ProcessEngine processEngine) {
28+
return processEngine.getRuntimeService();
29+
}
30+
31+
@Bean
32+
@DependsOn("processEngine")
33+
public HistoryService historyService(ProcessEngine processEngine) {
34+
return processEngine.getHistoryService();
35+
}
36+
}

multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/configuration/JmxConfiguration.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import java.util.Map;
44

5-
import jakarta.inject.Inject;
6-
75
import org.cloudfoundry.multiapps.controller.web.monitoring.Metrics;
86
import org.springframework.context.annotation.Bean;
97
import org.springframework.context.annotation.Configuration;
@@ -14,7 +12,6 @@ public class JmxConfiguration {
1412

1513
private static final String METRICS_BEAN = "org.cloudfoundry.multiapps.controller.web.monitoring:type=Metrics,name=MetricsMBean";
1614

17-
@Inject
1815
@Bean
1916
public MBeanExporter jmxExporter(Metrics metrics) {
2017
MBeanExporter mBeanExporter = new MBeanExporter();

multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/configuration/MicrometerConfiguration.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,31 @@
33
import java.text.MessageFormat;
44
import java.time.Duration;
55

6-
import jakarta.inject.Inject;
7-
6+
import io.micrometer.core.instrument.Clock;
7+
import io.micrometer.core.instrument.Metrics;
8+
import io.micrometer.core.instrument.config.MeterFilter;
9+
import io.micrometer.jmx.JmxConfig;
10+
import io.micrometer.jmx.JmxMeterRegistry;
811
import org.cloudfoundry.multiapps.controller.core.util.ApplicationConfiguration;
912
import org.cloudfoundry.multiapps.controller.persistence.util.EnvironmentServicesFinder;
1013
import org.slf4j.Logger;
1114
import org.slf4j.LoggerFactory;
1215
import org.springframework.context.annotation.Bean;
1316
import org.springframework.context.annotation.Configuration;
1417

15-
import io.micrometer.core.instrument.Clock;
16-
import io.micrometer.core.instrument.Metrics;
17-
import io.micrometer.core.instrument.config.MeterFilter;
18-
import io.micrometer.jmx.JmxConfig;
19-
import io.micrometer.jmx.JmxMeterRegistry;
20-
2118
@Configuration
2219
public class MicrometerConfiguration {
2320

2421
private static final Logger LOGGER = LoggerFactory.getLogger(MicrometerConfiguration.class);
2522
public static final String DYNATRACE_SERVICE_NAME = "deploy-service-dynatrace";
2623
private static final String CLIENT_CONNECTIONS_METRICS_PREFIX = "reactor.netty.connection.provider.cloudfoundry-client.";
2724

28-
@Inject
2925
@Bean
3026
public JmxMeterRegistry jmxMeterRegistry(ApplicationConfiguration configuration, EnvironmentServicesFinder vcapServiceFinder) {
3127
if (vcapServiceFinder.findJdbcService(DYNATRACE_SERVICE_NAME) == null) {
32-
LOGGER.warn(MessageFormat.format("Skipping registration of JmxMeterRegistry, since service \"{0}\" is not bound to the application.",
33-
DYNATRACE_SERVICE_NAME));
28+
LOGGER.warn(
29+
MessageFormat.format("Skipping registration of JmxMeterRegistry, since service \"{0}\" is not bound to the application.",
30+
DYNATRACE_SERVICE_NAME));
3431
return null;
3532
}
3633
Integer stepInSeconds = configuration.getMicrometerStepInSeconds();

multiapps-controller-web/src/main/java/org/cloudfoundry/multiapps/controller/web/configuration/UAAClientConfiguration.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.text.MessageFormat;
55
import java.util.Map;
66

7-
import jakarta.inject.Inject;
87
import org.cloudfoundry.multiapps.common.util.JsonUtil;
98
import org.cloudfoundry.multiapps.controller.client.facade.util.RestUtil;
109
import org.cloudfoundry.multiapps.controller.client.uaa.UAAClient;
@@ -17,7 +16,6 @@
1716
@Configuration
1817
public class UAAClientConfiguration {
1918

20-
@Inject
2119
@Bean
2220
public UAAClient uaaClient(ApplicationConfiguration configuration) {
2321
if (configuration.shouldSkipSslValidation()) {

0 commit comments

Comments
 (0)