Spring Autowire检索错误的类

时间:2019-06-13 13:39:43

标签: java spring-boot autowired

我有

public abstract class AbstractClass<T> {
  public abstract MyStatus getStatus();
  public void test() {
     System.out.println(getStatus().testField());
  }
}

对于我有的狗

@Component("dogs")
public class Dogs extends AbstractClass<Dogs>{
   @Autowired
   MyStatus statusField;

   @PostConstruct
   private void init() {
      statusField.setTest("dogs");
   }

   public getStatus() {
     return statusField;
   }
}

对于我拥有的猫

@Component("cats")
public class Cats extends AbstractClass<Cats>{
   @Autowired
   MyStatus statusField;

   @PostConstruct
   private void init() {
      statusField.setTest("cats");
   }

   public getStatus() {
     return statusField;
   }
}

,对于StatusContainer,我拥有

@Component
@Data
public class MyStatus<T> {
   public String test; // and other options from the application.properties file
}

我希望如果我@Autowired Dogs得到状态字段dogs,得到Cats,得到cats

public class ClassA {
   @Autowired
   @Qualifier("dogs")
   Dogs myDogEntity;
}

public class ClassB {
   @Autowired
   @Qualifier("cats")
   Cats myCatEntity;
}

事实上,如果我打印MyStatus的信息,我将每次cats(或每次dogs)得到。我本来希望容器以不同的方式启动并注入适当的实例。但这不是真的。

是否有一种简单方法来为不同的对象提供单独的容器,而不是注入相同的容器?

更新不幸的是,我的原始代码中有一些错字。修复了它们-希望所有。

我最终发现主要的问题是/仅是Spring创建了一个组件实例。就我而言,MyStatus。因此,这个实例被注入到其他类中。对该类的任何操作都将导致其对另一类的副作用。

我的解决方案:将配置分为两部分-一部分与Spring相关,另一部分与实例相关,例如CatsDogs将单独处理-无需使用Spring(注入)!

2 个答案:

答案 0 :(得分:1)

您的问题是,默认情况下,作用域在Spring上为Singleton,而您在Dogs和Cats中最终拥有相同的MyStatus实例。

有一个简单的方法可以实现,对于MyStatus类,可以将范围设置为Prototype:

@Data
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class MyStatus<T> {
   public String test; 
}

这样,您无需更改其他任何内容。因为Spring会为每个要求注入的实例创建一个新实例。

这样,“猫”和“狗”类将具有不同的MyStatus实例。

答案 1 :(得分:0)

您必须更新代码并更正键入错误,我已在下面发布了更正。

public class ClassA {
   @Autowired
   @Qualifier("dogs")
   Dogs myDogEntity;
}

public class ClassB {
   @Autowired
   @Qualifier("cats")
   Cats myCatEntity;
}