Jan Nielsen
Jan Nielsen

Reputation: 11849

@Bean ResourceProcessor with @Autowired

In my Spring Boot 1.5.10 application with Spring Data REST and HATEOAS, I have a ResourceProcessor bean with an @Autowired service, like:

@Bean
public ResourceProcessor<Resource<Order>> orderResourceProcessor() {
    return new ResourceProcessor<Resource<Order>>() {
        @Autowired
        private OrderHandler orderHandler;

        @Override
        public Resource<Order> process(Resource<Order> resource) {
            Order order = resource.getContent();
            Payment payment = orderHandler.payment(order);

            resource.add(makeLink(payment));

            return resource;
        }

        private Link makelink(Payment payment) {
            return new Link(/*...*/);
        }
    };
}

When the @Autowired service is added, the resource processor bean is no longer triggered, unfortunately; i.e., when OrderHandler is commented out, the resource processor runs as it should.

Can a ResourceProcessor use @Autowired services; and, if so, what's the right way to construct it?

Upvotes: 1

Views: 108

Answers (2)

cool
cool

Reputation: 1786

I guess you can Autowire orderHandler to outer class. In your way it will not work as you create the instance of ResourceProcessor yourself.

@Autowired
private OrderHandler orderHandler;

@Bean
public ResourceProcessor<Resource<Order>> orderResourceProcessor() {
   return new ResourceProcessor<Resource<Order>>() {


    @Override
    public Resource<Order> process(Resource<Order> resource) {
        Order order = resource.getContent();
        Payment payment = orderHandler.payment(order);

        resource.add(makeLink(payment));

        return resource;
    }

    private Link makelink(Payment payment) {
        return new Link(/*...*/);
    }
};
}

Upvotes: 2

davidxxx
davidxxx

Reputation: 131486

This part of the @Bean annotation javadoc should interest you :

@Bean Methods in @Configuration Classes

Typically, @Bean methods are declared within @Configuration classes. In this case, bean methods may reference other @Bean methods in the same class by calling them directly. This ensures that references between beans are strongly typed and navigable. Such so-called 'inter-bean references' are guaranteed to respect scoping and AOP semantics, just like getBean() lookups would.

Example :

 @Bean
 public FooService fooService() {
     return new FooService(fooRepository());
 }

 @Bean
 public FooRepository fooRepository() {
     return new JdbcFooRepository(dataSource());
 }

It means that you have not to use @Autowired to set the dependency inside the @Bean declaration but reference another method annotated with @Bean.
But do you really need to set the dependency to create your bean ? No at all. The OrderHandler is used only during the process() invocation.

So you can simply inject OrderHandler at the same level that the method annotated with @Bean and using it in the anonymous class :

@Autowired
private OrderHandler orderHandler;  // only change

@Bean
public ResourceProcessor<Resource<Order>> orderResourceProcessor() {
    return new ResourceProcessor<Resource<Order>>() {


        @Override
        public Resource<Order> process(Resource<Order> resource) {
            Order order = resource.getContent();
            Payment payment = orderHandler.payment(order);

            resource.add(makeLink(payment));

            return resource;
        }

        private Link makelink(Payment payment) {
            return new Link(/*...*/);
        }
    };
}

Upvotes: 2

Related Questions