Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-9044

Support simplified main class application context / dependency management

    Details

    • Type: Improvement
    • Status: Resolved
    • Priority: Minor
    • Resolution: Won't Fix
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Core
    • Labels:
    • Last commented by a User:
      false

      Description

      Problem

      One common request I see quite frequently on the internet is the ability to have spring autowire a main class:

      There is no shortage of questions / solutions to this problem which illustrates a need for a standardized approach.

      Solution

      What I am proposing is combination of features between the following existing classes:

      1. org.springframework.test.context.junit4.SpringJUnit4ClassRunner - provides functionality of the Spring TestContext Framework to standard JUnit 4.5+ tests
      2. org.springframework.test.context.ContextConfiguration - class-level metadata that is used to determine how to load and configure an ApplicationContext for test classes
      3. org.springframework.web.context.support.SpringBeanAutowiringSupport a convenient base class for self-autowiring classes that gets constructed within a Spring-based web application.

      Thus provinding first class support for console based application context management and DI.

      Features

      1. Autowiring of main class dependencies
      2. Auto-destruction of application context
      3. Ability in the future to handle command line arguments as beans

      Properties

      1. Standardization
      2. Consistency with other APIs
      3. Minimal configuration
      4. Intent revealing

      Example

      My visions is something like the following:

      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.context.MainSupport;
      import org.springframework.context.ContextConfiguration;
      import org.springframework.context.support.AnnotationConfigContextLoader;
      
      @ContextConfiguration(classes=AppConfig.class, loader=AnnotationConfigContextLoader.class)
      public class Main extends MainSupport {
          
          @Autowired
          private Service service;
      
          public static void main( String[] args ) {
              // MainSupport.execute
              execute(args);
          }
          
          @Main
          public void main() {
              service.run();
          }
          
      }
      

      The way this would work is as follows:

      1. JVM calls main
      2. main delegates to super class method MainSupport.execute provided by spring (analog of SpringBeanAutowiringSupport)
      3. MainSupport.execute reads the @ContextConfiguration annotation and looks for a @Main annotation (analog of @Test)
      4. MainSupport.execute creates the application context
      5. MainSupport.execute create an application Main class instance
      6. MainSupport.execute injects dependencies
      7. MainSupport.execute wraps instance in a proxy that will advise the method annotated with @Main. This proxy will first call the annotated method and then destroy the application context

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                pwebb Phil Webb
                Reporter:
                btiernay Bob Tiernay
                Last updater:
                Phil Webb
              • Votes:
                4 Vote for this issue
                Watchers:
                10 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Days since last comment:
                  4 years, 37 weeks, 6 days ago