Skip to content

Commit 3f3002e

Browse files
committed
spring ApplicationContext can be DI injected, ×WebApplicationContextUtils.getWebApplicationContext to upgrade to boot 3&jakarta
1 parent f58e5b3 commit 3f3002e

File tree

2 files changed

+41
-36
lines changed

2 files changed

+41
-36
lines changed

click-extras/src/main/java/org/apache/click/extras/spring/SpringClickServlet.java

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,22 @@
22

33
import lombok.EqualsAndHashCode;
44
import lombok.Getter;
5+
import lombok.NoArgsConstructor;
6+
import lombok.NonNull;
57
import lombok.RequiredArgsConstructor;
8+
import lombok.Setter;
69
import lombok.val;
710
import org.apache.click.ClickServlet;
811
import org.apache.click.Page;
12+
import org.jspecify.annotations.Nullable;
913
import org.springframework.beans.factory.BeanFactoryAware;
1014
import org.springframework.context.ApplicationContext;
1115
import org.springframework.context.ApplicationContextAware;
12-
import org.springframework.context.support.ClassPathXmlApplicationContext;
1316
import org.springframework.web.context.ContextLoader;
14-
import org.springframework.web.context.support.WebApplicationContextUtils;
17+
import org.springframework.web.context.WebApplicationContext;
1518

1619
import javax.servlet.ServletContext;
1720
import javax.servlet.ServletException;
18-
import javax.servlet.UnavailableException;
1921
import javax.servlet.http.HttpServletRequest;
2022
import java.beans.Introspector;
2123
import java.io.Serial;
@@ -319,22 +321,16 @@
319321
*
320322
* @see PageScopeResolver
321323
*/
324+
@NoArgsConstructor
322325
public class SpringClickServlet extends ClickServlet {
323326
@Serial private static final long serialVersionUID = -735025234764027175L;
324-
325327
/**
326328
* The Servlet initialization parameter name for the option to have the
327329
* SpringClickServlet inject Spring beans into page instances:  
328330
* <tt>"inject-page-beans"</tt>.
329331
*/
330332
public static final String INJECT_PAGE_BEANS = "inject-page-beans";
331333

332-
/**
333-
* The Servlet initialization parameter name for the path to the Spring XML
334-
* application context definition file: &nbsp; <tt>"spring-path"</tt>.
335-
*/
336-
public static final String SPRING_PATH = "spring-path";
337-
338334
/** The set of setter methods to ignore. */
339335
static final Set<String> SETTER_METHODS_IGNORE_SET = new HashSet<>();
340336
// Initialize the setter method ignore set
@@ -352,13 +348,16 @@ public class SpringClickServlet extends ClickServlet {
352348
}
353349

354350
/** Spring application context bean factory. */
355-
@Getter protected ApplicationContext applicationContext;
351+
@Getter @Setter protected @Nullable ApplicationContext applicationContext;
356352

357353
/** The list of page injectable Spring beans, keyed on page class name. */
358354
protected final Map<Class<? extends Page>, Set<BeanNameAndMethod>> pageSetterBeansMap = new ConcurrentHashMap<>();
359355

356+
public SpringClickServlet (@NonNull ApplicationContext applicationContext) {
357+
this.applicationContext = applicationContext;
358+
}//new
360359

361-
/**
360+
/**
362361
* Initialize the SpringClickServlet and the Spring application context
363362
* bean factory. An Spring <tt>ClassPathXmlApplicationContext</tt> bean
364363
* factory is used and initialize with the servlet <tt>init-param</tt>
@@ -372,25 +371,23 @@ public class SpringClickServlet extends ClickServlet {
372371
public void init () throws ServletException {
373372
super.init();
374373
ServletContext servletContext = getServletContext();
375-
applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
376374
if (applicationContext == null){
377-
applicationContext = ContextLoader.getCurrentWebApplicationContext();
375+
// WebApplicationContextUtils.getWebApplicationContext(servletContext):
376+
applicationContext = (ApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
377+
378+
if (applicationContext == null)
379+
applicationContext = ContextLoader.getCurrentWebApplicationContext();
380+
381+
if (applicationContext == null)
382+
throw new IllegalStateException("Can't find Spring ApplicationContext 🤷‍♀️");
378383
}
379-
if (applicationContext == null){
380-
String springPath = trim(getInitParameter(SPRING_PATH));
381-
if (springPath.isEmpty()){
382-
throw new UnavailableException(SPRING_PATH + " servlet init parameter not defined");
383-
}
384-
applicationContext = new ClassPathXmlApplicationContext(springPath);
385-
}
386384

387385
String injectPageBeans = trim(getInitParameter(INJECT_PAGE_BEANS));
388386
if ("true".equalsIgnoreCase(injectPageBeans)){
389387
// Process page classes looking for setter methods which match beans available in the applicationContext
390388
List<Class<? extends Page>> pageClassList = getConfigService().getPageClassList();
391-
for (Class<? extends Page> pageClass : pageClassList) {
392-
loadSpringBeanSetterMethods(pageClass);
393-
}
389+
for (Class<? extends Page> pageClass : pageClassList)
390+
loadSpringBeanSetterMethods(pageClass);
394391
}
395392
}
396393

@@ -434,7 +431,7 @@ protected Page newPageInstance(String path, Class<? extends Page> pageClass, Htt
434431
* @param page the page instance to activate
435432
*/
436433
@Override
437-
protected void activatePageInstance(Page page){
434+
protected void activatePageInstance (Page page) {
438435
if (page instanceof ApplicationContextAware aware){
439436
aware.setApplicationContext(applicationContext);
440437
} else if (page instanceof BeanFactoryAware aware){
@@ -460,7 +457,7 @@ protected void activatePageInstance(Page page){
460457
} catch (Exception error){
461458
throw new RuntimeException(error);
462459
}
463-
}
460+
}//f
464461
}
465462
}
466463
}
@@ -478,7 +475,7 @@ protected String toBeanName(Class<?> aClass) {
478475

479476
/** Provides a Spring bean name and page bean property setter method holder. */
480477
@RequiredArgsConstructor @EqualsAndHashCode
481-
static final class BeanNameAndMethod {
478+
protected static final class BeanNameAndMethod {
482479
/** The Spring bean name. */
483480
final String beanName;
484481
/** The page bean property setter method. */
@@ -510,4 +507,5 @@ private void loadSpringBeanSetterMethods(Class<? extends Page> pageClass) {
510507
}
511508
}
512509
}
510+
513511
}

click-freemarker/src/main/java/org/apache/click/extras/service/FreemarkerTemplateServiceSpring.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,18 @@
1212
import freemarker.template.TemplateModel;
1313
import lombok.Getter;
1414
import lombok.NonNull;
15+
import lombok.Setter;
1516
import lombok.ToString;
1617
import lombok.extern.slf4j.Slf4j;
1718
import lombok.val;
1819
import org.apache.click.service.ConfigService;
1920
import org.apache.click.service.TemplateService;
2021
import org.apache.click.util.ClickUtils;
2122
import org.springframework.beans.factory.BeanFactoryUtils;
23+
import org.springframework.context.ApplicationContext;
2224
import org.springframework.context.ApplicationEvent;
2325
import org.springframework.web.context.ContextLoader;
24-
import org.springframework.web.context.support.WebApplicationContextUtils;
26+
import org.springframework.web.context.WebApplicationContext;
2527

2628
import javax.servlet.ServletContext;
2729
import java.io.File;
@@ -42,6 +44,8 @@
4244
*/
4345
@Slf4j
4446
public class FreemarkerTemplateServiceSpring extends FreemarkerTemplateService {
47+
@Setter private ApplicationContext applicationContext;
48+
4549
/**
4650
* @see TemplateService#onInit(javax.servlet.ServletContext)
4751
*
@@ -109,18 +113,21 @@ public void onInit (@NonNull ServletContext servletContext) {
109113
log.warn("onInit: can't wrap ServletContext {}. {}", servletContext, this, e);
110114
}
111115

112-
var ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
113-
if (ctx == null){
114-
ctx = ContextLoader.getCurrentWebApplicationContext();
116+
if (applicationContext == null){
117+
// WebApplicationContextUtils.getWebApplicationContext(servletContext):
118+
applicationContext = (ApplicationContext) servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
119+
120+
if (applicationContext == null)
121+
applicationContext = ContextLoader.getCurrentWebApplicationContext();
115122
}
116-
if (ctx != null){
117-
try { //регистрируем ${Spring.freemarkerConfigurationBase.defaultEncoding}, Sql("")
118-
Map<String,TemplateModel> tmm = BeanFactoryUtils.beansOfTypeIncludingAncestors(ctx, TemplateModel.class, true, false);
123+
if (applicationContext != null){
124+
try {// register ${Spring.freemarkerConfigurationBase.defaultEncoding}, Sql("")
125+
Map<String,TemplateModel> tmm = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, TemplateModel.class, true, false);
119126
for (var tm : tmm.entrySet()){
120127
configuration.setSharedVariable(tm.getKey().trim(), tm.getValue());
121128
}
122-
configuration.setSharedVariable("spring", ctx);
123-
ctx.publishEvent(new FTLSvcConfiguredAppEvent(this, configuration, configService));
129+
configuration.setSharedVariable("spring", applicationContext);
130+
applicationContext.publishEvent(new FTLSvcConfiguredAppEvent(this, configuration, configService));
124131
} catch (Exception ignore){}
125132
}//i !null
126133

0 commit comments

Comments
 (0)