Skip to content

Commit f23f93f

Browse files
fix: register layout as beans for native build hints (#23006) (#23025)
Layout classes referenced by Vaadin routes are instantiated programmatically and they might contain annotation managed by Spring like `@PostConstruct`. This change discovers and registers layout classes as beans during AOT processing so that related information are available for native build. Fixes #23005 Co-authored-by: Marco Collovati <marco@vaadin.com>
1 parent c112252 commit f23f93f

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed

vaadin-spring/src/main/java/com/vaadin/flow/spring/springnative/VaadinBeanFactoryInitializationAotProcessor.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import com.vaadin.flow.component.Component;
4444
import com.vaadin.flow.component.ComponentEvent;
45+
import com.vaadin.flow.component.UI;
4546
import com.vaadin.flow.component.page.AppShellConfigurator;
4647
import com.vaadin.flow.router.HasErrorParameter;
4748
import com.vaadin.flow.router.HasUrlParameter;
@@ -187,10 +188,37 @@ private <T extends BeanFactory & BeanDefinitionRegistry> void findAndRegisterRou
187188
registeredClasses.add(c.getName());
188189
logger.debug("Registering a bean for route class {}",
189190
c.getName());
190-
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
191-
.rootBeanDefinition(c).setScope("prototype")
192-
.getBeanDefinition();
191+
AbstractBeanDefinition beanDefinition = createPrototypeBeanDefinition(
192+
c);
193193
beanFactory.registerBeanDefinition(c.getName(), beanDefinition);
194+
195+
// Layouts classes are instantiated programmatically, and they
196+
// might need to be
197+
// managed by Spring (e.g. because of @PostConstruct annotated
198+
// methods)
199+
Set<Class<? extends RouterLayout>> definedLayouts = new HashSet<>();
200+
if (c.isAnnotationPresent(Route.class)) {
201+
definedLayouts.add(c.getAnnotation(Route.class).layout());
202+
} else if (c.isAnnotationPresent(RouteAlias.class)) {
203+
definedLayouts
204+
.add(c.getAnnotation(RouteAlias.class).layout());
205+
} else if (c.isAnnotationPresent(RouteAlias.Container.class)) {
206+
for (RouteAlias alias : c
207+
.getAnnotation(RouteAlias.Container.class)
208+
.value()) {
209+
definedLayouts.add(alias.layout());
210+
}
211+
}
212+
definedLayouts.removeIf(
213+
layout -> registeredClasses.contains(layout.getName())
214+
|| layout == RouterLayout.class
215+
|| UI.class.isAssignableFrom(layout));
216+
for (Class<? extends RouterLayout> layout : definedLayouts) {
217+
beanFactory.registerBeanDefinition(layout.getName(),
218+
createPrototypeBeanDefinition(layout));
219+
registeredClasses.add(layout.getName());
220+
}
221+
194222
}
195223
}
196224

@@ -199,6 +227,12 @@ private <T extends BeanFactory & BeanDefinitionRegistry> void findAndRegisterRou
199227

200228
}
201229

230+
private static AbstractBeanDefinition createPrototypeBeanDefinition(
231+
Class<?> c) {
232+
return BeanDefinitionBuilder.rootBeanDefinition(c).setScope("prototype")
233+
.getBeanDefinition();
234+
}
235+
202236
private static Collection<Class<?>> getRouteTypesFor(String packageName) {
203237
return getAnnotatedClasses(packageName, Route.class, RouteAlias.class,
204238
Layout.class);

0 commit comments

Comments
 (0)