Как я могу назвать свои услуги в статическом блоке в 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();
}
}