设置后的属性总是为零

时间:2018-02-20 17:31:58

标签: java spring

我在osx上使用Eclipse的Spring版本3.0.6并且不明白为什么我不能为bean设置任何属性。部分代码:

@Component("desktopBuilderCallback")
@Scope("prototype")
public class DesktopBuilderCallback implements BuilderCallback {

  private Socket desktopSocket;

  @Override
  public Transformation afterTransform(Transformation transformation)
      throws Exception {

           \\ some implementation
  }


  @Override
  public void handleStatusUpdate(Transformation transformation)
      throws Exception
      {
       \\ some implementation
      }


  public Socket getDesktopSocket() {
    return desktopSocket;
  }

  public void setDesktopSocket(Socket desktopSocket) {
    this.desktopSocket = desktopSocket;
  }
}


@Component("transformationBuilder")
@Scope("prototype")
public class TransformationBuilder implements Runnable,
SourceNotificationCallback, TargetNotificationCallback,
ApplicationContextAware {

   int test;
   BuilderCallback builderCallback;

   public BuilderCallback getBuilderCallback() {
      return builderCallback;
   }

   public void setBuilderCallback(BuilderCallback builderCallback) {
      this.builderCallback = builderCallback;
   }

   public int getTest() {
      return this.test;
   }

  public void setTest(int theTest) {
      this.test = theTest;
  }
}

public static void main(String[] args) throws IOException {

    TransformationBuilder transformationBuilder = (TransformationBuilder) ctx.getBean("transformationBuilder");

    DesktopBuilderCallback callback = (DesktopBuilderCallback) ctx.getBean("desktopBuilderCallback");
    transformationBuilder.setBuilderCallback(callback);  
    transformationBuilder.setTest(5);
}

执行代码后,将不会初始化test和builderCallback。 test将为0且builderCallback为零。不确定它是怎么可能的,我是java和spring的新手......但是我已经检查过调试器跳转到setter(setTest,setBuilderCallback),可能是因为项目是为JRE 1.5开发的,但我是使用1.8 ...

1 个答案:

答案 0 :(得分:2)

从您发布的代码到目前为止,我猜您的问题与将bean的范围设置为prototype有关。

来自spring docs

  

bean的非单例原型范围部署导致每次发出特定bean的请求时都会创建一个新的bean实例(也就是说,它被注入另一个bean或者它是通过对容器的程序化getBean()方法调用请求的。根据经验,您应该将原型范围用于所有有状态的bean,而单例范围应该用于无状态bean。

这是每次从应用程序上下文(transformationBuilder)获取ctx.getBean("transformationBuilder") bean时,您将获得TransformationBuilder新实例。每个不属于标准bean初始化过程的手动初始化都不会在这些实例中可用。

要正确初始化bean,可以使用@Value注释从配置中注入值,使用@Autowired注入其他bean实例,或使用@PostConstruct方法执行其他非bean - 通过初始化。

对于你的课程,这可能是这样的:

@Component("transformationBuilder")
@Scope("prototype")
public class TransformationBuilder implements Runnable,
        SourceNotificationCallback, TargetNotificationCallback,
        ApplicationContextAware {

   // either use the value of the property 'some.property.key' or 5 as default
   @Value("${some.property.key:5}")
   int test;

   @Autowired
   @Qualifier("desktopBuilderCallback")
   BuilderCallback builderCallback;

   ...
}

当然,您也可以使用singleton范围(实际上是spring bean的默认范围)。每次请求此bean时,这将导致spring返回相同实例。但是对于singleton范围,bean的初始化也应该由DI容器处理。