基于工厂类的类不可用于自动装配。

huangapple go评论97阅读模式
英文:

Class based on factory class not available for autowiring

问题

我正在尝试学习Spring的基础知识,并定义了以下类:

public class Processor {

    public Processor() {
        this.setup();
    }

    private void setup(){
       //运行一些设置代码
    }

    public String processString(String str) {
        //处理字符串
        return str;
    }

}

我想要使用工厂bean使这个类能在Spring中启用,所以我使用了一个工厂bean:

阅读了 https://www.baeldung.com/spring-factorybean 后,我这样使用:

public class Processor implements FactoryBean<Processor> {

    @Override
    public Processor getObject() throws Exception {
        return new Processor();
    }

    @Override
    public Class<?> getObjectType() {
        return Processor.class;
    }
}

进行测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ProcessorFactory.class)
public class ProcessorTest {

    @Autowired
    private Processor processor;

    @Test
    public void testProcessor() {
        //一些测试
    }
}

这按预期工作。

但是,当我尝试在项目的其他地方使用以下代码:

@Autowired
private Processor processor;

我会收到编译时错误:

Could not autowire. No beans of 'Processor' type found.

我是否没有正确设置工厂?我应该给Processor对象加上注解,以指示它需要自动装配吗?或许这不是Factory的有效用例?

英文:

I'm trying to learn the basics of Spring and have defined this class?

public class Processor {

    public Processor() {
        this.setup();
    }

    private void setup(){
       //run some setup code
    }

    public String processString(String str) {
        // process the string
        return str;
    }

}

I want to Spring enable this class so I use a factory bean:

Reading https://www.baeldung.com/spring-factorybean I use:

public class Processor implements FactoryBean&lt;Processor&gt; {

    @Override
    public Processor getObject() throws Exception {
        return new Processor();
    }

    @Override
    public Class&lt;?&gt; getObjectType() {
        return Processor.class;
    }
}

To Test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ProcessorFactory.class)
public class ProcessorTest {

    @Autowired
    private Processor processor;

        @Test
    public void testProcessor() {
            //Some tests
        }
}

This works as expected.

When I try to use

@Autowired
private Processor processor;

elsewhere in my project I receive compile-time error :

Could not autowire. No beans of &#39;Processor&#39; type found.

Have I not setup the factory correctly? I should annotate the Processor object to indicate it is to be autowired ? Perhaps this is not a valid use case for Factory ?

答案1

得分: 2

总体来说,工厂bean已经相当过时了,最初的Spring版本确实使用了这种方法,但是自那时以来Spring已经发展了许多。

工厂bean本身应该在Spring配置中进行注册(最早的Spring版本使用基于XML的配置,因为当时还不存在Java注解),所以教程中包含了XML配置示例。无论如何,这可能是失败的原因。在测试中,您还应该指定xml配置的路径,否则工厂bean将无法加载。

您可以使用这些工厂bean(它们仍然受支持),但它们具有以下缺点:

  1. 它们将您的代码与Spring框架耦合在一起。
  2. 有很多样板代码(通常在典型应用程序中可能会有数百个bean,因此为每个bean创建一个工厂bean就显得过于繁琐)。

所以您可以:

  1. 不要使用工厂bean,而是使用@Component注解(或更专业的@Service注解)对Processor进行注解。

  2. 或者使用Java配置:

@Configuration
public class MyConfig {
  
  @Bean
  public Processor processor() {
      // 可选地根据需要稍微自定义类的创建;
      return new Processor();
  }
}
英文:

In general, factory beans are pretty outdated, first spring versions indeed used this approach, but spring has evolved since that time.

The Factory bean itself should be registered in the spring configuration (the very first versions of spring used xml based configuration because Java Annotation did not exist at that time) so the tutorial contains the XML configuration example. Anyway, that's probably the reason of failure. In the test you should also specify the path to the xml configuration otherwise the factory bean won't be loaded.

You can use these factory beans (they're still supported) but they have the following downsides:

  1. They couple your code to the spring framework
  2. A lot of boilerplate (usually in typical application there can be hundreds of beans, so creating a Factory Bean for each one is an overkill).

So you can:

  1. Instead of using Factory Beans, annotate the Processor with @Component annotation (or more specialized @Service).

  2. Alternatively Use Java configuration:


@Configration
public class MyConfig {
  
  @Bean
  public Processor processor() {
      // optionally slightly customize the creation of the class if required;
      return new Processor();
  }
}

huangapple
  • 本文由 发表于 2020年8月31日 15:55:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/63666894.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定