0

I have a strange behaviour with a Spring Data Rest implementation (version 2.5.2.RELEASE).

I'm trying to register a @Bean of ResourceProcessor<Resource<Entity>>, but there is something strange.

I'm trying with two kinds of solutions:

1) Declaring the @Bean in a class:

@Bean
public ResourceProcessor<Resource<Author>> authorProcessor() {

    return new ResourceProcessor<Resource<Author>>() {

        @Override
        public Resource<Author> process(Resource<Author> resource) {

            System.out.println("method process of bean ResourceProcessor of class RepositoryBaseConfiguration");
            return resource;
        }
    };
}

2) Implementing the interface ResourceProcessor:

@Component
public class AuthorResourceProcessor implements ResourceProcessor<Resource<Author>> {

    @Override
    public Resource<Author> process(Resource<Author> resource) {
        System.out.println("method process of class AuthorResourceProcessor");
        return resource;
    }

}

The processors are completely ignored: the message is never printed.

I noticed that the class org.springframework.data.rest.webmvc.ResourceProcessorInvoker has a constructor:

public ResourceProcessorInvoker(Collection<ResourceProcessor<?>> processors) {

    //...
}

This constructor is invoked 2 times at the start of the application instead of only one time (as I will expect), and I don't understand why.

The first time, the "processors" variable is solved with the two beans (as expected) and with the bean org.springframework.data.rest.webmvc.ProfileResourceProcessor.

But the second time, the "processors" variable is solved with only the bean org.springframework.data.rest.webmvc.ProfileResourceProcessor.

The second configuration @Override the first one.

Any idea?

Alessandro C
  • 3,310
  • 9
  • 46
  • 82

1 Answers1

0

The problem depends on the configurations loaded at the startup of the application.

I had this configuration on the web.xml:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/spring-web-config.xml</param-value>
</context-param>

<servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>org.springframework.data.rest.webmvc.RepositoryRestDispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

So, the ContextLoaderListener loaded the correct configuration in the first time; the "load-on-startup" property of the servlet "RepositoryRestDispatcherServlet" launch a second context configuration load.

I also had a custom class that extended org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration, but this custom class was ignored by the moment that the constructor of RepositoryRestDispatcherServlet load the default RepositoryRestMvcConfiguration, causing the lost of the configurations.

To solve that issue I have created a custom RepositoryRestDispatcherServlet in this way:

public class AppRepositoryRestDispatcherServlet extends DispatcherServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public AppRepositoryRestDispatcherServlet() {
        configure();
    }

    public AppRepositoryRestDispatcherServlet(WebApplicationContext webApplicationContext) {
        super(webApplicationContext);
        configure();
    }

    private void configure() {
        setContextClass(AnnotationConfigWebApplicationContext.class);
        setContextConfigLocation(RepositoryBaseConfiguration.class.getName());
    }

}

The class is the same as RepositoryRestDispatcherServlet, with the only difference that in the setContextConfigLocation is passed the custom class that extends RepositoryRestMvcConfiguration (RepositoryBaseConfiguration in this example).

Obviously I had to update the web.xml as follows:

<servlet>
    <servlet-name>rest</servlet-name>
    <servlet-class>my.package.AppRepositoryRestDispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

In this way, the configuration is correctly loaded and mantained.

Alessandro C
  • 3,310
  • 9
  • 46
  • 82