22
33import lombok .EqualsAndHashCode ;
44import lombok .Getter ;
5+ import lombok .NoArgsConstructor ;
6+ import lombok .NonNull ;
57import lombok .RequiredArgsConstructor ;
8+ import lombok .Setter ;
69import lombok .val ;
710import org .apache .click .ClickServlet ;
811import org .apache .click .Page ;
12+ import org .jspecify .annotations .Nullable ;
913import org .springframework .beans .factory .BeanFactoryAware ;
1014import org .springframework .context .ApplicationContext ;
1115import org .springframework .context .ApplicationContextAware ;
12- import org .springframework .context .support .ClassPathXmlApplicationContext ;
1316import org .springframework .web .context .ContextLoader ;
14- import org .springframework .web .context .support . WebApplicationContextUtils ;
17+ import org .springframework .web .context .WebApplicationContext ;
1518
1619import javax .servlet .ServletContext ;
1720import javax .servlet .ServletException ;
18- import javax .servlet .UnavailableException ;
1921import javax .servlet .http .HttpServletRequest ;
2022import java .beans .Introspector ;
2123import java .io .Serial ;
319321 *
320322 * @see PageScopeResolver
321323 */
324+ @ NoArgsConstructor
322325public 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: <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}
0 commit comments