手动创建实例时如何使@autowire 在 spring 中工作

How to make @autowire work in spring when creating instance manually


我有一个 java 接口说 ITest 由两个 classes Class1 和 Class2 实现。现在我有一个工厂 class,我用它来决定哪个实现 return。喜欢

if(something)
    return new Class1()
else
   return new Class2()

问题是我在 Class1 中有自动装配字段,它没有被实例化,但是相同的自动装配在其他 classes 中工作,它们是通过自动装配实例化的。
这是 Class1

的代码
@Componene
public Class1 implements ITest{
  @Autowired
  private SomeClass obj;
}

不确定如何解决这个问题。由于 SomeClass 的自动装配在其他 classes.

中工作正常

在您的工厂中注入 applicationContext class 并将其用于创建 bean:

@Autowired private ApplicationContext applicationContext;
......
......
         if(something){
            return applicationContext.getBean("com.xyz.Class1");
         }
......
......

或者您可以在 Class1 和 Class2 之上使用 @Configurable。这需要启用 AspectJ 编织。 Spring 将在您使用 new 时神奇地创建 bean。

您可以使用带有@SpringBootApplication 或@Configuration 注释的主配置class。

示例:

@SpringBootApplication
public class YourApp {

   public static void main(String[] args) {
       SpringApplication.run(YourApp.class, args);
   }

   @Autowired
   private CsvBeanRepository repo;

   @Bean
   public InterfaceSome some() {
       if(something) {
           return new Some(repo);
       } else {
           return new Some2(repo);
       }
   }
}

在 @SpringBootApplication class 或 @Configuration class 中,您可以正常地 @Autowire 您的 classes 并将它们用作工厂的参数。

这在很大程度上取决于您究竟需要什么,但您可以:

  1. 将工厂returned 的对象定义为原型范围并将其注入到单例中,有关详细信息,请参阅:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-sing-prot-interaction

然后整个魔法由Spring

完成
  1. 如果你只是想在两个不同的无状态实现之间切换,你可以将它们都注入到工厂和 return 一个现有的 bean

    @Compoment class Factory { 
    
      @Autowired 
      Class1 class1Instance;
    
      @Autowired 
      Class2 classInstance;
      ...
      if(something)
        return class1Instance;
      else
       return class2Instance;
      ...
    }
    

    }

但请确保注入的两个 类 都没有状态。

  1. 让工厂由 Spring 管理,类 不由 Spring 管理,并手动注入依赖项:

    public Class1 implements ITest{
    
      private SomeClass obj;
    
      public Class1(SomeClass obj) {
            this.obj=obj;}
    }
    

在工厂:

  @Autowired
  private SomeClass obj;
   ...
   if(something)
     return new Class1(obj);
   else
    return new Class2(obj);

乍一看很奇怪,这样你就可以例如单独的域和 application/infrastructure 部分。

我建议在这种情况下使用@value 注释。

例子

我的班级{

Object getObjectFromFactory()
{
  if(something)
    return new Class1()
 else
    return new Class2()
}

}

那么就可以像下面这样使用了

@Value("#{MyClass.getObjectFromFactory}")

私有对象 myObject;