带有@Autowired的@Bean ResourceProcessor

时间:2018-03-21 18:55:08

标签: java spring-boot spring-rest

在使用Spring Data REST和HATEOAS的Spring Boot 1.5.10应用程序中,我有一个ResourceProcessor bean,其中包含@Autowired服务,如:

@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(/*...*/);
        }
    };
}

添加@Autowired服务时,遗憾的是不再触发资源处理器bean;即,当注释掉OrderHandler时,资源处理器将按预期运行。

ResourceProcessor可以使用@Autowired服务;如果是的话,构建它的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

我猜你可以将orderHandler自动装配到外类。按照自己的方式,它将无法自行创建ResourceProcessor实例。

@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(/*...*/);
    }
};
}

答案 1 :(得分:2)

@Bean annotation javadoc的这一部分应引起您的兴趣:

@Configuration类中的@Bean方法

  

通常,@ Node方法在@Configuration类中声明。   在这种情况下,bean方法可以引用其中的其他@Bean方法   同一个班直接打电话给他们。这确保了引用   bean之间是强类型和可导航的。这样所谓   &#39; bean间引用&#39;保证尊重范围和AOP   语义,就像getBean()查找一样。

示例:

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

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

这意味着您不必使用@Autowired@Bean声明中设置依赖关系,而是引用另一个使用@Bean注释的方法。
但是你真的需要设置依赖项来创建你的bean吗? 一点也不。 OrderHandler仅在process()调用期间使用。

因此,您只需将OrderHandler注入与@Bean注释的方法相同的级别,并在匿名类中使用它:

@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(/*...*/);
        }
    };
}