Как вызвать ArrayList, хранящийся в applicationScope из другого класса
Я хочу вызвать ArrayList, хранящийся в applicationScope из другого класса
У меня есть класс, что-то вроде этого, который хранит скачок данных в открытых именах переменных AL_data, метод getAllData просто хранит данные в AL_data
public class Application implements Serializable{
private static final long serialVersionUID = 1L;
public ArrayList<District> AL_data;
public Application(){
try {
getAllData();
} catch (NotesException e) {
e.printStackTrace();
}
}
}
И я установил класс как управляемый bean-компонент в face-config, используя applicationScope
<managed-bean>
<managed-bean-name>App</managed-bean-name>
<managed-bean-class>com.utils.Application</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
У меня также есть другой класс, который я хочу использовать для чтения области приложения
public class actions {
private static Map<String, Object> applicationScope() {
FacesContext context = FacesContext.getCurrentInstance();
return (Map<String, Object>) context.getApplication().getVariableResolver().resolveVariable(context,"applicationScope");
}
public Vector<String> getDataForCurrentUser() {
try {
// how do I access the AL_data arraylist stored in applicationscope
// ArrayList m = (ArrayList) this.applicationScope();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
и я установил этот класс как компонент управления с помощью sessionScope.
<managed-bean>
<managed-bean-name>Actions</managed-bean-name>
<managed-bean-class>com.utils.actions</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
Я хотел бы знать, как я могу вызвать класс области приложения и получить доступ к его общедоступным свойствам, или как я могу вернуть свой ArrayList.
Спасибо
Томас
2 ответа
Добавьте общедоступный метод к своему компоненту, который могут использоваться другими классами Java для доступа к экземпляру этого компонента:
public static Application get() {
FacesContext context = FacesContext.getCurrentInstance();
return (Application) context.getApplication().getVariableResolver().resolveVariable("App");
}
Затем вы можете использовать этот метод, чтобы получить доступ к экземпляру bean-объекта области действия из вашего класса Actions, а затем получить доступ к методам и переменным этого bean-компонента:
public class actions {
public Vector<String> getDataForCurrentUser() {
// Access the AL_data arraylist stored in the App application scoped bean
ArrayList<District> m = Application.get().AL_data;
}
Пока правила области видимости позволяют это сделать, наилучшим подходом является позволить инфраструктуре обрабатывать внедрение свойств и bean-компонентов в другие bean-компоненты.
Поскольку вам нужен bean-объект с областью приложения внутри bean-объекта сессионной области, вы можете просто определить внедрение следующим образом:
<managed-bean>
<managed-bean-name>Actions</managed-bean-name>
<managed-bean-class>com.utils.actions</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>application</property-name>
<value>#{App}</value>
</managed-property>
</managed-bean>
Чтобы принять инъекцию свойства в ваш бин Actions, определите открытый метод следующим образом:
public class actions implements Serializable {
private Application app;
public void setApplication(Application app) {
this.app = app;
}
}
Таким образом, вы можете получить доступ к компоненту приложения в любом месте, где вам это нужно, в классе, без необходимости разрешать его снова и снова, когда вам это нужно. Вы также можете решить, что ссылка на компонент приложения - это слишком много, и вам просто нужны данные. На этом этапе вам просто нужно настроить faces-config.xml
и способ получения соответственно, чтобы получить именно это.
<managed-property>
<property-name>allData</property-name>
<value>#{App.allData}</value>
</managed-property>
public class actions implements Serializable {
private static final long serialVersionUID = 1L;
private ArrayList<District> allData;
public void setAllData(ArrayList<District> allData) {
this.allData = allData;
}
}
Теперь два совета.
- Я бы не рекомендовал вам инициализировать данные компонента в конструкторе. Бины предназначены для ленивого использования, и поэтому данные должны быть лениво загружены. Если вам нужно предварительно загрузить данные, конструктор не в нужном месте. К сожалению, мы застряли с нежитью XPages, поэтому нет ничего лучше, чем исправить проблему, проверив, установлена ли рассматриваемая переменная или нет. Это означает использование подхода, подобного этому:
public class Application implements Serializable {
private static final long serialVersionUID = 1L;
private ArrayList<District> allData;
//public Application(){
// try {
// getAllData();
// } catch (NotesException e) {
// e.printStackTrace();
// }
//}
public ArrayList<District> getAllData() {
if (allData == null) {
try {
allData = // your logic result
} catch (NotesException e) {
throw new FacesException(e);
}
}
return allData;
}
}
- Я бы посоветовал вам использовать общепринятые соглашения об именах, которые говорят, что имена свойств должны начинаться с символов в нижнем регистре (приложение вместо приложения) и имен классов с символа в верхнем регистре (com.utils.Actions вместо com.utils.actions)