@Bean ResourceProcessor 和 @Autowired

@Bean ResourceProcessor with @Autowired

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

@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 服务吗?如果是这样,构建它的正确方法是什么?

我猜你可以将 orderHandler 自动连接到外部 class。在您自己创建 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(/*...*/);
    }
};
}

@Bean annotation javadoc 的这一部分您应该感兴趣:

@Configuration 中的@Bean 方法类

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.

示例:

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

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

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

因此您可以简单地将 OrderHandler 注入到与 @Bean 注释的方法相同的级别,并在匿名 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(/*...*/);
        }
    };
}