3333import org .springframework .beans .BeansException ;
3434import org .springframework .beans .factory .BeanFactory ;
3535import org .springframework .beans .factory .BeanFactoryAware ;
36+ import org .springframework .beans .factory .BeanNotOfRequiredTypeException ;
3637import org .springframework .beans .factory .NoSuchBeanDefinitionException ;
3738import org .springframework .beans .factory .config .BeanPostProcessor ;
3839import org .springframework .beans .factory .config .ConfigurableListableBeanFactory ;
@@ -45,26 +46,30 @@ public class NonRootBeanPostProcessor implements BeanPostProcessor, BeanFactoryA
4546
4647 private final @ Nonnull TemporalProperties temporalProperties ;
4748 private final @ Nullable List <NonRootNamespaceProperties > namespaceProperties ;
48- private final @ Nullable Tracer tracer ;
49- private final @ Nullable TestWorkflowEnvironmentAdapter testWorkflowEnvironment ;
50- private final @ Nullable Scope metricsScope ;
51-
52- public NonRootBeanPostProcessor (
53- @ Nonnull TemporalProperties temporalProperties ,
54- @ Nullable Tracer tracer ,
55- @ Nullable TestWorkflowEnvironmentAdapter testWorkflowEnvironment ,
56- @ Nullable Scope metricsScope ) {
49+ private @ Nullable Tracer tracer ;
50+ private @ Nullable TestWorkflowEnvironmentAdapter testWorkflowEnvironment ;
51+ private @ Nullable Scope metricsScope ;
52+
53+ public NonRootBeanPostProcessor (@ Nonnull TemporalProperties temporalProperties ) {
5754 this .temporalProperties = temporalProperties ;
5855 this .namespaceProperties = temporalProperties .getNamespaces ();
59- this .tracer = tracer ;
60- this .testWorkflowEnvironment = testWorkflowEnvironment ;
61- this .metricsScope = metricsScope ;
6256 }
6357
6458 @ Override
65- public Object postProcessAfterInitialization (Object bean , String beanName ) throws BeansException {
59+ public Object postProcessAfterInitialization (@ Nonnull Object bean , @ Nonnull String beanName )
60+ throws BeansException {
6661 if (bean instanceof NamespaceTemplate && beanName .equals ("temporalRootNamespaceTemplate" )) {
6762 if (namespaceProperties != null ) {
63+ // If there are non-root namespaces, we need to inject beans for each of them. Look
64+ // up the bean manually instead of using @Autowired to avoid circular dependencies or causing the dependency to
65+ // get initialized to early and skip post-processing.
66+ //
67+ // Note: We don't use @Lazy here because these dependencies are optional and @Lazy doesn't interact well with
68+ // optional dependencies.
69+ metricsScope = findBean ("temporalMetricsScope" , Scope .class );
70+ tracer = findBean (Tracer .class );
71+ testWorkflowEnvironment =
72+ findBean ("temporalTestWorkflowEnvironment" , TestWorkflowEnvironmentAdapter .class );
6873 namespaceProperties .forEach (this ::injectBeanByNonRootNamespace );
6974 }
7075 }
@@ -163,6 +168,24 @@ private <T> T findBeanByNamespace(String beanPrefix, Class<T> clazz) {
163168 return null ;
164169 }
165170
171+ private <T > @ Nullable T findBean (Class <T > clazz ) {
172+ try {
173+ return beanFactory .getBean (clazz );
174+ } catch (NoSuchBeanDefinitionException | BeanNotOfRequiredTypeException ignore ) {
175+ // Ignore if the bean is not found or not of the required type
176+ }
177+ return null ;
178+ }
179+
180+ private <T > @ Nullable T findBean (String beanName , Class <T > clazz ) {
181+ try {
182+ return beanFactory .getBean (beanName , clazz );
183+ } catch (NoSuchBeanDefinitionException | BeanNotOfRequiredTypeException ignore ) {
184+ // Ignore if the bean is not found or not of the required type
185+ }
186+ return null ;
187+ }
188+
166189 private <T > TemporalOptionsCustomizer <T > findBeanByNameSpaceForTemporalCustomizer (
167190 String beanPrefix , Class <T > genericOptionsBuilderClass ) {
168191 String beanName =
0 commit comments