cer / event-sourcing-examples

Example code for my building and deploying microservices with event sourcing, CQRS and Docker presentation
Other
3.12k stars 946 forks source link

Support Observable as @Controller return value #4

Closed rstoyanchev closed 9 years ago

rstoyanchev commented 9 years ago

Pull request for issue #3. I didn't manage to run the examples but the following change should make it possible to return Observable from a controller method.

cer commented 9 years ago

I tried running the tests and got:

< HTTP/1.1 406 Not Acceptable
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< X-Application-Context: application
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Thu, 28 May 2015 22:06:07 GMT
rstoyanchev commented 9 years ago

When I run the tests I get "PLEASE make sure that Event Store-related environment variables including EVENT_STORE_URL are set, see sample-set-remote-env.sh !!!!". I see sample-set-server-env.sh but I'm not sure how to set those variables. The README says the build is configured to ignore failures related to the event store.

It sounds like the tests may not be picking up the ObservableReturnValueHandler registration (e.g. in CommandSideWebAccountsConfiguration) so it probably tries to render the Observable and fails to find a message converter that can do that. It would help to see some logging at DEBUG level for org.springframework.web, also which test fails?

Theoretically the change is a functionally neutral refactoring if you compare to what is done in DeferredResultMethodReturnValueHandler. Nevertheless I would also recommend upgrading to Boot 1.2.x to raise the Spring Framework level to 4.1 from 4.0.x which is a good idea in any case since we currently support 4.1.x and 3.2.x only.

cer commented 9 years ago

Thanks for looking into this.

The easiest way to test the application without the event store server (i would need to send you credentials) is to run the tests in the monolithic-service module. That's an all in one service and the tests use the embedded event store. You just need to set export SPRING_DATA_MONGODB_URI=mongodb://192.168.59.103/mydb

You could also build the monolithic service and run it 'java -jar' and use curl commands in handy-curl-commands.sh

I upgraded to Spring Boot 1.2.3

I had wondered whether @EnableWebMvc (need to RTFM) was needed but adding it made no difference.

This is what i see in the logs

07:01:56.758  DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'managementServerProperties'
07:01:56.759  DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'dispatcherServlet' processing POST request for [/accounts]
07:01:56.762  DEBUG o.s.b.a.e.mvc.EndpointHandlerMapping - Looking up handler method for path /accounts
07:01:56.762  DEBUG o.s.b.a.e.mvc.EndpointHandlerMapping - Did not find handler method for [/accounts]
07:01:56.762  DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /accounts
07:01:56.764  DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Returning handler method [public rx.Observable<net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountResponse> net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.AccountController.createAccount(net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountRequest)]
07:01:56.764  DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'accountController'
07:01:56.786  DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Reading [class net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountRequest] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@76502684]
07:01:56.827  DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'transactionManager'
07:01:56.831  DEBUG o.s.j.d.DataSourceTransactionManager - Creating new transaction with name [net.chrisrichardson.eventstore.jdbc.JdbcEventStoreService.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
07:01:56.831  DEBUG o.s.j.d.SimpleDriverDataSource - Creating new JDBC Driver Connection to [jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false]
07:01:56.832  DEBUG o.s.j.d.DataSourceTransactionManager - Acquired Connection [conn3: url=jdbc:h2:mem:testdb user=SA] for JDBC transaction
07:01:56.834  DEBUG o.s.j.d.DataSourceTransactionManager - Switching JDBC Connection [conn3: url=jdbc:h2:mem:testdb user=SA] to manual commit
07:01:56.845  DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL update
07:01:56.846  DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [INSERT INTO entities (entity_type, entity_id, entity_version) VALUES (?, ?, ?)]
07:01:56.849  DEBUG o.s.jdbc.core.JdbcTemplate - SQL update affected 1 rows
07:01:56.852  DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL update
07:01:56.852  DEBUG o.s.jdbc.core.JdbcTemplate - Executing prepared SQL statement [INSERT INTO events (event_id, event_type, event_data, entity_type, entity_id, triggering_event) VALUES (?, ?, ?, ?, ?, ?)]
07:01:56.853  DEBUG o.s.jdbc.core.JdbcTemplate - SQL update affected 1 rows
07:01:56.854  DEBUG o.s.j.d.DataSourceTransactionManager - Initiating transaction commit
07:01:56.854  DEBUG o.s.j.d.DataSourceTransactionManager - Committing JDBC transaction on Connection [conn3: url=jdbc:h2:mem:testdb user=SA]
07:01:56.855  DEBUG o.s.j.d.DataSourceTransactionManager - Releasing JDBC Connection [conn3: url=jdbc:h2:mem:testdb user=SA] after transaction
07:01:56.855  DEBUG o.s.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
07:01:56.887  DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception from handler [public rx.Observable<net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountResponse> net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.AccountController.createAccount(net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountRequest)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
07:01:56.888  DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from handler [public rx.Observable<net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountResponse> net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.AccountController.createAccount(net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountRequest)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
07:01:56.888  DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from handler [public rx.Observable<net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountResponse> net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.AccountController.createAccount(net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CreateAccountRequest)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
07:01:56.889  DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
07:01:56.889  DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
07:01:56.901  DEBUG o.s.web.servlet.DispatcherServlet - DispatcherServlet with name 'dispatcherServlet' processing POST request for [/error]
07:01:56.901  DEBUG o.s.b.a.e.mvc.EndpointHandlerMapping - Looking up handler method for path /error
07:01:56.901  DEBUG o.s.b.a.e.mvc.EndpointHandlerMapping - Did not find handler method for [/error]
07:01:56.901  DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Looking up handler method for path /error
07:01:56.901  DEBUG o.s.w.s.m.m.a.RequestMappingHandlerMapping - Returning handler method [public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
07:01:56.901  DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'basicErrorController'
07:01:56.945  DEBUG o.s.w.s.m.m.a.HttpEntityMethodProcessor - Written [{timestamp=Fri May 29 07:01:56 PDT 2015, status=406, error=Not Acceptable, exception=org.springframework.web.HttpMediaTypeNotAcceptableException, message=Could not find acceptable representation, path=/accounts}] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@76502684]
07:01:56.946  DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapter completed request handling
07:01:56.946  DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
07:01:56.946  DEBUG o.s.web.client.RestTemplate - POST request for "http://localhost:63770/accounts" resulted in 406 (Not Acceptable); invoking error handler
rstoyanchev commented 9 years ago

Looks like this is harder than I thought. I've created https://jira.spring.io/browse/SPR-13083. I'll send an updated request.

rstoyanchev commented 9 years ago

I've updated the PR. The monolithic-service module test passes now.

Note that since the monolithic service imports the web configuration of 3 other web modules (which otherwise probably run independent of each other, right?) it ends up with 3 instances of ObservableReturnValueHandler. It's not ideal but I didn't feel it was necessary to go farther since the monolithic-service is probably there just for illustration purposes.

cer commented 9 years ago

For some reason the monolithic test was failing with this error:

java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:103)
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:98)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:331)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:213)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:290)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:292)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:233)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:87)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:176)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:105)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355)
    at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:744)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'querySideWebConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter net.chrisrichardson.eventstore.javaexamples.banking.web.queryside.QuerySideWebConfiguration.adapter; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration.setConfigurers(java.util.List); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'commandSideWebAccountsConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CommandSideWebAccountsConfiguration.adapter; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'requestMappingHandlerAdapter': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:107)
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:69)
    at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:95)
    ... 44 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter net.chrisrichardson.eventstore.javaexamples.banking.web.queryside.QuerySideWebConfiguration.adapter; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration.setConfigurers(java.util.List); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'commandSideWebAccountsConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CommandSideWebAccountsConfiguration.adapter; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'requestMappingHandlerAdapter': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:522)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:298)
    ... 60 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration.setConfigurers(java.util.List); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'commandSideWebAccountsConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CommandSideWebAccountsConfiguration.adapter; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'requestMappingHandlerAdapter': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:370)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1095)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:990)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1021)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:964)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:494)
    ... 62 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration.setConfigurers(java.util.List); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'commandSideWebAccountsConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CommandSideWebAccountsConfiguration.adapter; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'requestMappingHandlerAdapter': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:610)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:298)
    ... 82 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'commandSideWebAccountsConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CommandSideWebAccountsConfiguration.adapter; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'requestMappingHandlerAdapter': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1021)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:916)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:567)
    ... 84 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter net.chrisrichardson.eventstore.javaexamples.banking.web.commandside.accounts.CommandSideWebAccountsConfiguration.adapter; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'requestMappingHandlerAdapter': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:522)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:298)
    ... 95 more
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'requestMappingHandlerAdapter': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:334)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1021)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:964)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:494)
    ... 97 more

I fixed it by using this hack to eliminate the @Autowire:

    class FakeThing {}

    @Bean
    public FakeThing init(RequestMappingHandlerAdapter adapter) {
        // https://jira.spring.io/browse/SPR-13083
        List<HandlerMethodReturnValueHandler> handlers = new ArrayList<HandlerMethodReturnValueHandler>(adapter.getReturnValueHandlers());
        handlers.add(0, new ObservableReturnValueHandler());
        adapter.setReturnValueHandlers(handlers);
        return new FakeThing();
    }
dgomesbr commented 9 years ago

@cer and @rstoyanchev to work around ordering issues, couldn't you use Ordered annotation with lowest precedence?