Cache names found by types in AppBeans and ComponentsFactory. #PL-5836

This commit is contained in:
Konstantin Krivopustov 2015-08-21 08:34:08 +00:00
parent 534c3fd9ad
commit 77c20dc740
3 changed files with 50 additions and 34 deletions

View File

@ -5,6 +5,7 @@
package com.haulmont.cuba.desktop.gui;
import com.haulmont.cuba.core.global.DevelopmentException;
import com.haulmont.cuba.desktop.gui.components.*;
import com.haulmont.cuba.gui.ComponentPalette;
import com.haulmont.cuba.gui.components.*;
@ -13,6 +14,7 @@ import com.haulmont.cuba.gui.xml.layout.ComponentsFactory;
import javax.annotation.ManagedBean;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author krivopustov
@ -23,6 +25,8 @@ public class DesktopComponentsFactory implements ComponentsFactory {
private static Map<String, Class<? extends Component>> classes = new HashMap<>();
private static Map<Class, String> names = new ConcurrentHashMap<>();
static {
classes.put(Window.NAME, DesktopWindow.class);
classes.put(Window.Editor.NAME, DesktopWindow.Editor.class);
@ -108,20 +112,20 @@ public class DesktopComponentsFactory implements ComponentsFactory {
@Override
public <T extends Component> T createComponent(Class<T> type) {
String name = null;
java.lang.reflect.Field nameField;
try {
nameField = type.getField("NAME");
name = (String) nameField.get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
//ignore
}
if (name != null) {
return type.cast(createComponent(name));
} else {
throw new IllegalStateException(String.format("Class '%s' doesn't have NAME property", type.getName()));
String name = names.get(type);
if (name == null) {
java.lang.reflect.Field nameField;
try {
nameField = type.getField("NAME");
name = (String) nameField.get(null);
} catch (NoSuchFieldException | IllegalAccessException ignore) {
}
if (name == null)
throw new DevelopmentException(String.format("Class '%s' doesn't have NAME field", type.getName()));
else
names.put(type, name);
}
return type.cast(createComponent(name));
}
@Override

View File

@ -10,6 +10,8 @@ import com.haulmont.cuba.core.sys.AppContext;
import javax.annotation.Nullable;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
/**
* Provides access to all managed beans of the application.
@ -19,6 +21,8 @@ import java.util.Map;
*/
public class AppBeans {
private static Map<Class, Optional<String>> names = new ConcurrentHashMap<>();
/**
* Return the bean instance that matches the given object type.
* If the provided bean class contains a public static field <code>NAME</code>, this name is used to look up the
@ -27,15 +31,20 @@ public class AppBeans {
* @return an instance of the single bean matching the required type
*/
public static <T> T get(Class<T> beanType) {
// Try to find bean name defined in its NAME static field
String name = null;
try {
Field nameField = beanType.getField("NAME");
name = (String) nameField.get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
// ignore
Optional<String> optName = names.get(beanType);
if (optName == null) {
// Try to find a bean name defined in its NAME static field
try {
Field nameField = beanType.getField("NAME");
name = (String) nameField.get(null);
} catch (NoSuchFieldException | IllegalAccessException ignore) {
}
names.put(beanType, Optional.ofNullable(name));
} else {
name = optName.orElse(null);
}
// If the name found, look up the bean by name because it is much faster
// If the name is found, look up the bean by name because it is much faster
if (name == null)
return AppContext.getApplicationContext().getBean(beanType);
else

View File

@ -4,6 +4,7 @@
*/
package com.haulmont.cuba.web.gui;
import com.haulmont.cuba.core.global.DevelopmentException;
import com.haulmont.cuba.gui.ComponentPalette;
import com.haulmont.cuba.gui.components.*;
import com.haulmont.cuba.gui.components.mainwindow.*;
@ -14,6 +15,7 @@ import com.haulmont.cuba.web.gui.components.mainwindow.*;
import javax.annotation.ManagedBean;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author krivopustov
@ -24,6 +26,8 @@ public class WebComponentsFactory implements ComponentsFactory {
private static Map<String, Class<? extends Component>> classes = new HashMap<>();
private static Map<Class, String> names = new ConcurrentHashMap<>();
static {
classes.put(Window.NAME, WebWindow.class);
classes.put(Window.Editor.NAME, WebWindow.Editor.class);
@ -124,21 +128,20 @@ public class WebComponentsFactory implements ComponentsFactory {
@Override
public <T extends Component> T createComponent(Class<T> type) {
// TODO Java8: replace with MethodHandle
String name = null;
java.lang.reflect.Field nameField;
try {
nameField = type.getField("NAME");
name = (String) nameField.get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
//ignore
}
if (name != null) {
return type.cast(createComponent(name));
} else {
throw new IllegalStateException(String.format("Class '%s' doesn't have NAME property", type.getName()));
String name = names.get(type);
if (name == null) {
java.lang.reflect.Field nameField;
try {
nameField = type.getField("NAME");
name = (String) nameField.get(null);
} catch (NoSuchFieldException | IllegalAccessException ignore) {
}
if (name == null)
throw new DevelopmentException(String.format("Class '%s' doesn't have NAME field", type.getName()));
else
names.put(type, name);
}
return type.cast(createComponent(name));
}
@Override