<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=scottyfred" rel="nofollow">Scott Frederick</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-6693?redirect=false" rel="nofollow">SPR-6693</a></strong> and commented</p>
<p dir="auto">Spring MVC <code class="notranslate">@ExceptionHandler</code> controller methods support a flexible argument list and return value, similiar to <code class="notranslate">@RequestMapping-annotated</code> methods. One option that is supported by <code class="notranslate">@RequestMapping</code> methods but not <code class="notranslate">@ExceptionHandler</code> methods is returning naked bean objects from the exception handler method.</p>
<p dir="auto">For example, this type of exception handler method would be very convenient, especially when building RESTful services using a MarshallingView (the important detail is the "HelloResponse" return value from the handleBindException method):</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@Controller
@RequestMapping(&quot;/Hello&quot;)
public class HelloController {
  @RequestMapping(value = &quot;/greet&quot;, method = RequestMethod.GET)
  public HelloResponse greetGet(@Valid HelloRequest request) {
    String message = &quot;Hello, &quot; + request.getTitle() + &quot; &quot; + request.getName();
    return new HelloResponse(message);
  }

  @ExceptionHandler(BindException.class)
  public HelloResponse handleBindException(BindException be) {
    List&lt;FieldError&gt; errors = be.getFieldErrors();
    HelloResponse response = new HelloResponse();
    for (FieldError error : errors) {
      response.addError(error.toString());
    }
    return response;
  }
}"><pre class="notranslate"><code class="notranslate">@Controller
@RequestMapping("/Hello")
public class HelloController {
  @RequestMapping(value = "/greet", method = RequestMethod.GET)
  public HelloResponse greetGet(@Valid HelloRequest request) {
    String message = "Hello, " + request.getTitle() + " " + request.getName();
    return new HelloResponse(message);
  }

  @ExceptionHandler(BindException.class)
  public HelloResponse handleBindException(BindException be) {
    List&lt;FieldError&gt; errors = be.getFieldErrors();
    HelloResponse response = new HelloResponse();
    for (FieldError error : errors) {
      response.addError(error.toString());
    }
    return response;
  }
}
</code></pre></div>
<p dir="auto">With a response object that looks like this:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="@XmlRootElement(name = &quot;response&quot;)
public class HelloResponse {
  private String message;
  private List&lt;String&gt; errors;
  // getters and setters
}"><pre class="notranslate"><code class="notranslate">@XmlRootElement(name = "response")
public class HelloResponse {
  private String message;
  private List&lt;String&gt; errors;
  // getters and setters
}
</code></pre></div>
<p dir="auto">Currently this code will throw an exception when the exception handler method returns to the framework:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="java.lang.IllegalArgumentException: Invalid handler method return value: HelloResponse@caf0ed
	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver.getModelAndView(AnnotationMethodHandlerExceptionResolver.java:353)
	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver.doResolveException(AnnotationMethodHandlerExceptionResolver.java:101)
	at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:109)
	at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1004)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:792)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)"><pre class="notranslate"><code class="notranslate">java.lang.IllegalArgumentException: Invalid handler method return value: HelloResponse@caf0ed
	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver.getModelAndView(AnnotationMethodHandlerExceptionResolver.java:353)
	at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver.doResolveException(AnnotationMethodHandlerExceptionResolver.java:101)
	at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:109)
	at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1004)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:792)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:716)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:647)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:552)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
</code></pre></div>
<hr>
<p dir="auto"><strong>Affects:</strong> 3.0 GA</p>
<p dir="auto"><strong>Attachments:</strong></p>
<ul dir="auto">
<li><a href="https://jira.spring.io/secure/attachment/16092/ExceptionHandler-return.patch" rel="nofollow">ExceptionHandler-return.patch</a> (<em>5.70 kB</em>)</li>
</ul>
<p dir="auto">13 votes, 19 watchers</p>
<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=btiernay" rel="nofollow">Bob Tiernay</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-9044?redirect=false" rel="nofollow">SPR-9044</a></strong> and commented</p>
<h2 dir="auto">Problem</h2>
<p dir="auto">One common request I see quite frequently on the internet is the ability to have spring autowire a main class:</p>
<ul dir="auto">
<li><a href="http://hvijay.wordpress.com/2011/07/02/spring-dependency-injection-in-applications-main-class/" rel="nofollow">http://hvijay.wordpress.com/2011/07/02/spring-dependency-injection-in-applications-main-class/</a></li>
<li><a href="http://forum.springsource.org/archive/index.php/t-47933.html" rel="nofollow">http://forum.springsource.org/archive/index.php/t-47933.html</a></li>
<li><a href="http://stackoverflow.com/questions/6820724/how-to-inject-properties-into-a-spring-bean-from-main-class" rel="nofollow">http://stackoverflow.com/questions/6820724/how-to-inject-properties-into-a-spring-bean-from-main-class</a></li>
<li><a href="http://stackoverflow.com/questions/8313070/spring-bean-injection-in-main-method-class" rel="nofollow">http://stackoverflow.com/questions/8313070/spring-bean-injection-in-main-method-class</a></li>
<li><a href="http://stackoverflow.com/questions/3659720/spring-3-autowire-in-standalone-application" rel="nofollow">http://stackoverflow.com/questions/3659720/spring-3-autowire-in-standalone-application</a></li>
<li><a href="http://stackoverflow.com/questions/4787719/spring-console-application-configured-using-annotations" rel="nofollow">http://stackoverflow.com/questions/4787719/spring-console-application-configured-using-annotations</a></li>
<li><a href="http://forum.springsource.org/showthread.php?75991-ContextConfiguration" rel="nofollow">http://forum.springsource.org/showthread.php?75991-ContextConfiguration</a></li>
</ul>
<p dir="auto">There is no shortage of questions / solutions to this problem which illustrates a need for a standardized approach.</p>
<h2 dir="auto">Solution</h2>
<p dir="auto">What I am proposing is combination of features between the following existing classes:</p>
<ol dir="auto">
<li><code class="notranslate">org.springframework.test.context.junit4.SpringJUnit4ClassRunner</code> - provides functionality of the Spring TestContext Framework to standard JUnit 4.5+ tests</li>
<li><code class="notranslate">org.springframework.test.context.ContextConfiguration</code> - class-level metadata that is used to determine how to load and configure an ApplicationContext for test classes</li>
<li><code class="notranslate">org.springframework.web.context.support.SpringBeanAutowiringSupport</code> a convenient base class for self-autowiring classes that gets constructed within a Spring-based web application.</li>
</ol>
<p dir="auto">Thus provinding first class support for console based application context management and DI.</p>
<h2 dir="auto">Features</h2>
<ol dir="auto">
<li>Autowiring of main class dependencies</li>
<li>Auto-destruction of application context</li>
<li>Ability in the future to handle command line arguments as beans</li>
</ol>
<h2 dir="auto">Properties</h2>
<ol dir="auto">
<li>Standardization</li>
<li>Consistency with other APIs</li>
<li>Minimal configuration</li>
<li>Intent revealing</li>
</ol>
<h2 dir="auto">Example</h2>
<p dir="auto">My visions is something like the following:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="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();
    }
    
}"><pre class="notranslate"><code class="notranslate">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();
    }
    
}
</code></pre></div>
<p dir="auto">The way this would work is as follows:</p>
<ol dir="auto">
<li>JVM calls <code class="notranslate">main</code></li>
<li><code class="notranslate">main</code> delegates to super class method <code class="notranslate">MainSupport.execute</code> provided by spring (analog of <code class="notranslate">SpringBeanAutowiringSupport</code>)</li>
<li><code class="notranslate">MainSupport.execute</code> reads the <code class="notranslate">@ContextConfiguration</code> annotation and looks for a <code class="notranslate">@Main</code> annotation (analog of <code class="notranslate">@Test</code>)</li>
<li><code class="notranslate">MainSupport.execute</code> creates the application context</li>
<li><code class="notranslate">MainSupport.execute</code> create an application <code class="notranslate">Main</code> class instance</li>
<li><code class="notranslate">MainSupport.execute</code> injects dependencies</li>
<li><code class="notranslate">MainSupport.execute</code> wraps instance in a proxy that will advise the method annotated with <code class="notranslate">@Main</code>. This proxy will first call the annotated method and then destroy the application context</li>
</ol>
<hr>
<p dir="auto"><strong>Issue Links:</strong></p>
<ul dir="auto">
<li><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="398110895" data-permission-text="Title is private" data-url="https://github.com/spring-projects/spring-framework/issues/12732" data-hovercard-type="issue" data-hovercard-url="/spring-projects/spring-framework/issues/12732/hovercard" href="https://github.com/spring-projects/spring-framework/issues/12732">#12732</a> Provide Java main() for launching Spring applications</li>
</ul>
<p dir="auto">4 votes, 10 watchers</p>