如何在Java中的静态块中调用我的服务

时间:2014-05-12 04:09:50

标签: java spring zk zul

我正在使用ZK Charts在我的ZK框架中构建HighCharts。在Model Java File中,他们使用Static块来加载模型中的硬编码值。例如

static {
    model = new DefaultCategoryModel();
    model.setValue("John", "Apples", new Integer(5));
    model.setValue("John", "Oranges", new Integer(3));
    model.setValue("John", "Pears", new Integer(4));
    model.setValue("John", "Grapes", new Integer(7));
    model.setValue("John", "Bananas", new Integer(2));
    model.setValue("Jane", "Apples", new Integer(2));
    model.setValue("Jane", "Oranges", new Integer(2));
    model.setValue("Jane", "Pears", new Integer(3));
    model.setValue("Jane", "Grapes", new Integer(2));
    model.setValue("Jane", "Bananas", new Integer(1));
    model.setValue("Joe", "Apples", new Integer(3));
    model.setValue("Joe", "Oranges", new Integer(4));
    model.setValue("Joe", "Pears", new Integer(4));
    model.setValue("Joe", "Grapes", new Integer(2));
    model.setValue("Joe", "Bananas", new Integer(5));
}

我的图表很好但是默认值。现在我想让它充满活力。我有几项服务为我提供库存水平的产品。我的想法是想要使用这些图表显示低库存警报。

我试图在静态块中调用这些服务,但它会抛出空指针异常。

public class BarStackedData
{
private static CategoryModel model;

@Autowired
private static DefaultCustomCommerceCartService defaultCustomCommerceCartService;

@Autowired
private static ProductService productService;

static
{
    model = new DefaultCategoryModel();

    model.setValue(
            "Low Stock",
            "Puma T-Shirts",
            new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023506"),
                    null)));
    model.setValue(
            "Low Stock",
            "Socks",
            new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023206"),
                    null)));

    ....... more code .....

}

public static CategoryModel getCategoryModel()
{
    return model;
}

我知道Static block是一个静态初始化器。它将在加载类时执行。但有没有什么方法可以让它变得动态或者如何用动态值显示这些图形。

记录:

SEVERE: Servlet.service() for servlet [zkLoader] in context with path [/backoffice] threw       exception [Servlet java.lang.NullPointerException
    at com.rfn.model.BarStackedData.<clinit>(BarStackedData.java:30)
    at com.rfn.widgets.BarStackedComposerController.doAfterCompose(BarStackedComposerController.java:22)
    at com.rfn.widgets.BarStackedComposerController.doAfterCompose(BarStackedComposerController.java:1)

2 个答案:

答案 0 :(得分:3)

静态块中的代码可能在您自动装配的变量被设置之前执行 - 因此NullPointerException。

您可以尝试使用@PostConstruct创建一个方法并对其进行注释,并且在正确配置所有内容后,框架将调用该方法。

@Service
public class BarStackedData
{
    private CategoryModel model;

    @Autowired
    private DefaultCustomCommerceCartService defaultCustomCommerceCartService;

    @Autowired
    private ProductService productService;

    @PostConstruct
    private void setupModel()
    {
        model = new DefaultCategoryModel();

        model.setValue(
                "Low Stock",
                "Puma T-Shirts",
                new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023506"),
                null)));
        model.setValue(
                "Low Stock",
                "Socks",
                new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023206"),
                null)));

        ....... more code .....

    }

    public CategoryModel getCategoryModel()
    {
        return model;
    }
}

修改

您需要通过静态方法接口,以便外部图表库可以访问数据。这是我的解决方案,它使用facade类来保持静态方法远离主服务:

@Service
public class BarStackedData
{
    private CategoryModel model;

    @Autowired
    private DefaultCustomCommerceCartService defaultCustomCommerceCartService;

    @Autowired
    private ProductService productService;

    @PostConstruct
    private void setupModel()
    {
        model = new DefaultCategoryModel();

        model.setValue(
                "Low Stock",
                "Puma T-Shirts",
                new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023506"),
                null)));
        model.setValue(
                "Low Stock",
                "Socks",
                new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023206"),
                null)));

        ....... more code .....

    }

    public CategoryModel getCategoryModel()
    {
        return model;
    }
}


@Component
public class DataFacade {

    private static BarStackedData barStackedModel = null;

    @Autowired
    private setBarStackedData(final BarStackedData barStackedModel) {
        DataFacade.barStackedModel = barStackedModel;
    }

    public static CategoryModel getCategoryModel() {
        return barStackedModel.getCategoryModel();
    }

}

答案 1 :(得分:1)

为什么使用静态阻止。没有它你也可以完成你的工作。

试试这个..

public class BarStackedData
{

   private static CategoryModel model;
   private static DefaultCustomCommerceCartService defaultCustomCommerceCartService;
   private static ProductService productService;

   public static CategoryModel getCategoryModel()
   {
        model = new DefaultCategoryModel();

        model.setValue(
        "Low Stock",
        "Puma T-Shirts",
        new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023506"),
                null)));
        model.setValue(
        "Low Stock",
        "Socks",
        new Long(defaultCustomCommerceCartService.getCustomAvailableStockLevel(productService.getProductForCode("30023206"),
                null)));

      ....... more code .....

      return model;
   }

   // Getter Method
   public DefaultCustomCommerceCartService getDefaultCustomCommerceCartService()
   {
      return defaultCustomCommerceCartService;
   }

   // Setter Method
   public void setProductService(ProductService productService)
   {
      this.productService = productService;
   }

}

现在在spring.xml文件中注册bean

<bean id="barStackedData" class="com.java.project.BarStackedData" >
    <property name="defaultCustomCommerceCartService" ref="defaultCustomCommerceCartService" />
    <property name="productService" ref="productService" />
</bean>

正如我在ZK Chart中看到的,他们正在使用Controller。尝试通过Registry获取bean。

public class BarStackedComposer extends SelectorComposer<Window> 
{
@Wire
Charts chart;

BarStackedData barStackedData;

public void doAfterCompose(Window comp) throws Exception {
    super.doAfterCompose(comp);

    // get spring bean 
    barStackedData = (BarStackedData) Registry.getApplicationContext().getBean("barStackedData");

    chart.setModel(BarStackedData.getCategoryModel());

    chart.getYAxis().setMin(0);
    chart.getYAxis().setTitle("Total fruit consumption");

    chart.getLegend().setBackgroundColor("#FFFFFF");
    chart.getLegend().setReversed(true);

    chart.getPlotOptions().getSeries().setStacking("normal");

    chart.getCredits().setEnabled(false);
 }
}

希望这会帮助你...享受:)