Инициализация управляемого компонента ApplicationScope
Я создал управляемый компонент, который считывает последовательность документов из представления и создает запись HashMap для каждого из документов. Каждая запись хэш-карты содержит ряд значений, извлеченных из документа. Эти значения редко изменяются и используются во многих местах. В любом случае здание HashMap работает и хранит правильные значения. Если я создаю конструктор следующим образом:
private final Map<String, AppProperties> internalMap = new HashMap<String, AppProperties>();
public ApplicationMap() {
System.out.println("In Constructor");
if (this.internalMap.isEmpty()){
System.out.println("Is Empty ");
this.buildMap(this.internalMap);
}
}
Конструктор всегда видит internalMap как пустой и перестраивает его. Я пытался сделать то же самое в методе Get (делая конструктор общедоступным ApplicationMap() {})
Проверка, имеет ли оно значение:
public AppProperties get(Object key) {
System.out.println("in Get");
try {
if (this.internalMap.containsKey(key)) {
System.out.println("Has Key" + key);
return this.internalMap.get(key);
} else {
this.buildMap(this.internalMap);
if (this.internalMap.containsKey(key)) {
System.out.println("Has Key" + key);
return this.internalMap.get(key);
} else {
System.out.println("No Key in ApplicationMap " + key);
AppProperties ap = new AppProperties();
return ap;
}
}
} catch (Exception e) {
System.out.println("ApplicationMap" + e.toString());
AppProperties ap = new AppProperties();
return ap;
}
}
но это, кажется, никогда не находит значение ключа и проходит через this.buildMap каждый раз. Так что я явно что-то упускаю. Я думаю, что размещение buildMap в get, кажется, является правильным местом для этого, но
Вот сокращенный код buildMap:
private void buildMap(Map<String, AppProperties> theMap) {
try {
Session s = ExtLibUtil.getCurrentSession();
mainDB = s.getCurrentDatabase();
vwApps = mainDB.getView("vwWFSApplicationsEnabled");
serverName = s.createName(mainDB.getServer()).getCommon();
veCol = vwApps.getAllEntries();
ve = veCol.getFirstEntry();
tVE = null;
while (ve != null) {
AppProperties ap = new AppProperties();
tVE = veCol.getNextEntry(ve);
colVal = ve.getColumnValues();
appName = colVal.get(0).toString();
System.out.println("Application = " + appName);
String tAppRepID = colVal.get(3).toString();
ap.setAppRepID(colVal.get(3).toString());
ap.setHelpRepID(colVal.get(4).toString());
ap.setRuleRepID(colVal.get(5).toString());
System.out.println("Put Map");
theMap.put(appName, ap);
//System.out.println("Recycle ve");
ve.recycle();
ve = tVE;
}
//System.out.println("Finished Loop");
} catch (Exception e) {
System.out.println(e.toString());
} finally {
Utils.recycleObjects( vwApps, vwForms, ve, veCol,);
//System.out.println("Finally Finished");
}
}
2 ответа
Конструктор всегда вызывается только для объекта, всегда. Вот почему internalMap
всегда пуст в конструкторе.
Не давайте вашему приватному методу buildMap параметр и доступ internalMap
там прямой вместо
У меня есть аксиома разработки программного обеспечения - ошибки, которые легко найти, трудно исправить, в то время как ошибки, которые трудно найти, легко исправить, и это классический случай. Решение состоит в том, что, когда я вызываю bean-компонент из SSJS, я использовал sysntax: WFSAppProperties(). Get(Some Key Value).getAppFilePath(); При этом внутренняя карта всегда считалась пустой, однако она должна быть следующей: WFSAppProperties.get(Some Key Value).getAppFilePath(); Оба случая возвращают правильное значение, но первый всегда перезагружает internalMap, в то время как второй загружает InternalMap только один раз при начальной загрузке, как и должно быть. При вызове EL он всегда работал правильно. Спасибо Кнуту за его время и терпение в борьбе с бобом JAVA Newby.