Как я могу назвать свои услуги в статическом блоке в Java

Я использую ZK Charts для построения HighCharts в моей среде ZK. В Java-файле модели они используют статический блок для загрузки жестко закодированного значения в модель. Например

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;
}

Я знаю, что Статический блок является статическим инициализатором. Это будет выполнено, когда класс загружен. Но есть ли способ сделать его динамичным или как я могу показать эти пару графиков с динамическими значениями.

Журнал:

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 ответа

Решение

Почему вы используете статический блок. Вы можете сделать свою работу без этого также.

Попробуй это..

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 id="barStackedData" class="com.java.project.BarStackedData" >
    <property name="defaultCustomCommerceCartService" ref="defaultCustomCommerceCartService" />
    <property name="productService" ref="productService" />
</bean>

Как я видел в ZK Chart, они используют контроллер. Попробуйте получить бин через реестр.

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);
 }
}

Надеюсь, это поможет вам... наслаждайтесь:)

Код в статическом блоке, вероятно, выполняется до того, как будут установлены переменные, которые вы автоматически подключаете - таким образом, исключение 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;
    }
}

редактировать

У вас есть требование, чтобы интерфейс был статическим методом, чтобы внешняя библиотека диаграмм могла получить доступ к данным. Вот мое решение, которое использует класс фасадов для предотвращения использования статических методов вдали от основного сервиса:

@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();
    }

}
Другие вопросы по тегам