Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Improve Spring To Spring Beans definition compatibility - MEED-7576 - Meeds-io/meeds#2469 #986

Merged
merged 1 commit into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
*/
package io.meeds.spring.kernel;

import static io.meeds.spring.kernel.KernelContainerLifecyclePlugin.addSpringContext;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
Expand All @@ -25,7 +28,6 @@
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;

import org.exoplatform.container.PortalContainer;
import org.exoplatform.container.RootContainer.PortalContainerPostInitTask;

import jakarta.servlet.ServletContext;

Expand All @@ -48,20 +50,13 @@ public PortalApplicationContext(ServletContext servletContext, DefaultListableBe

@Override
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
BeanDefinitionRegistry beanRegistry = (BeanDefinitionRegistry) beanFactory;
// Declare spring Context for integration on Kernel when it will start
// ( Kernel container is always started after all Spring contexts are
// started, see "PortalContainersCreator" in Meeds-io/meeds project )
KernelContainerLifecyclePlugin.addSpringContext(servletContext.getServletContextName(), this, beanRegistry);

// Delay Spring context finishing startup until the Kernel container is
// fully started
PortalContainer.addInitTask(servletContext, new PortalContainerPostInitTask() {
@Override
public void execute(ServletContext context, PortalContainer portalContainer) {
finishSpringContextStartup(beanFactory);
}
}, "portal");
addSpringContext(servletContext.getServletContextName(),
this,
(BeanDefinitionRegistry) beanFactory,
() -> finishSpringContextStartup(beanFactory));
}

@Override
Expand All @@ -72,11 +67,18 @@ protected void finishRefresh() {
private void finishSpringContextStartup(ConfigurableListableBeanFactory beanFactory) {
long start = System.currentTimeMillis();
LOG.info("Continue Spring context '{}' initialization", servletContext.getServletContextName());
PortalApplicationContext.super.finishBeanFactoryInitialization(beanFactory);
PortalApplicationContext.super.finishRefresh();
LOG.info("Spring context '{}' initialized in {}ms",
servletContext.getServletContextName(),
System.currentTimeMillis() - start);
try {
PortalApplicationContext.super.finishBeanFactoryInitialization(beanFactory);
PortalApplicationContext.super.finishRefresh();
LOG.info("Spring context '{}' initialized in {}ms",
servletContext.getServletContextName(),
System.currentTimeMillis() - start);
} catch (Exception e) {
throw new IllegalStateException(String.format("Error While finishing Beans Initialization in context '%s' with Bean names [%s] (May be related to issue Meeds-io/meeds#2469)",
servletContext.getServletContextName(),
StringUtils.join(beanFactory.getBeanDefinitionNames(), " , ")),
e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;

/**
* A super class used to define {@link PortalApplicationContext} as the Spring
* Application Builder to use
*/
public abstract class PortalApplicationContextInitializer extends SpringBootServletInitializer {

private DefaultListableBeanFactory beanFactory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
LOG.info("Integrating Spring Context with Container. Application name = '{}' using Kernel configuration class '{}'",
applicationContext.getApplicationName(),
getTestClass());
addSpringContext("test", applicationContext, (BeanDefinitionRegistry) beanFactory);
addSpringContext("test", applicationContext, (BeanDefinitionRegistry) beanFactory, null);
bootContainer(getTestClass());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* This file is part of the Meeds project (https://meeds.io/).
*
* Copyright (C) 2020 - 2023 Meeds Association [email protected]
* Copyright (C) 2020 - 2024 Meeds Association [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
Expand All @@ -18,33 +18,10 @@
*/
package io.meeds.spring.module.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import org.exoplatform.commons.api.settings.SettingService;

import io.meeds.spring.module.model.TestModel;
import io.meeds.spring.module.storage.TestStorage;

@Service
public class TestService {

// Fake injection from Kernel for Testing Purpose
@Autowired
private SettingService settingService;

@Autowired
private TestStorage storage;
public interface TestService {

public TestModel save(TestModel model) {
if (model == null) {
throw new IllegalArgumentException("TestModel is mandatory");
}
if (settingService == null) {
// Fake exception
throw new IllegalStateException("SettingService is null");
}
return storage.save(model);
}
TestModel save(TestModel testModel);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* This file is part of the Meeds project (https://meeds.io/).
*
* Copyright (C) 2020 - 2024 Meeds Association [email protected]
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package io.meeds.spring.module.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import org.exoplatform.commons.api.settings.SettingService;

import io.meeds.spring.module.model.TestModel;
import io.meeds.spring.module.storage.TestStorage;

@Service
public class TestServiceImpl implements TestService {

// Fake injection from Kernel for Testing Purpose
@Autowired
private SettingService settingService;

@Autowired
private TestStorage storage;

@Override
public TestModel save(TestModel model) {
if (model == null) {
throw new IllegalArgumentException("TestModel is mandatory");
}
if (settingService == null) {
// Fake exception
throw new IllegalStateException("SettingService is null");
}
return storage.save(model);
}

}