Better caching proxy using CGlib

Allows internal calls to this.getBlah() to also be cached.
This commit is contained in:
Kris De Volder
2018-07-12 16:06:43 -07:00
parent 1c376bcbea
commit 4b31ac99ee
7 changed files with 111 additions and 62 deletions

View File

@@ -78,15 +78,14 @@ public abstract class AbstractSpringBootApp implements SpringBootApp {
@Override
public abstract boolean isSpringBootApp();
@Override
public JMXConnector getJmxConnector() throws MalformedURLException, IOException {
protected JMXConnector getJmxConnector() throws MalformedURLException, IOException {
JMXServiceURL serviceUrl = getJmxUrl();
JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceUrl, null);
return jmxConnector;
}
@Override
public final List<String> getActiveProfiles() {
public List<String> getActiveProfiles() {
try {
String _env = getEnvironment();
if (_env != null) {
@@ -161,7 +160,7 @@ public abstract class AbstractSpringBootApp implements SpringBootApp {
}
@Override
public final LiveBeansModel getBeans() {
public LiveBeansModel getBeans() {
try {
String domain = getDomainForActuator();
String json = getBeansFromActuator(domain);
@@ -200,7 +199,7 @@ public abstract class AbstractSpringBootApp implements SpringBootApp {
* @return JMX MBean domain containing actuator information, or null if not resolved.
* @throws Exception when resolving domain from JMX
*/
protected final String getDomainForActuator() throws Exception {
protected String getDomainForActuator() throws Exception {
if (this.jmxMbeanActuatorDomain == null) {
JMXConnector jmxConnector = null;
try {
@@ -252,7 +251,7 @@ public abstract class AbstractSpringBootApp implements SpringBootApp {
}
}
protected final Object getActuatorDataFromAttribute(ObjectName objectName, String attribute) throws Exception {
protected Object getActuatorDataFromAttribute(ObjectName objectName, String attribute) throws Exception {
JMXConnector jmxConnector = null;
try {
if (objectName != null) {
@@ -273,7 +272,7 @@ public abstract class AbstractSpringBootApp implements SpringBootApp {
}
}
protected final Object getActuatorDataFromOperation(ObjectName objectName, String operation) throws Exception {
protected Object getActuatorDataFromOperation(ObjectName objectName, String operation) throws Exception {
JMXConnector jmxConnector = null;
try {
if (objectName != null) {

View File

@@ -1,45 +0,0 @@
/*******************************************************************************
* Copyright (c) 2018 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.boot.app.cli;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
public class NoArgumentsCacheHandler implements InvocationHandler {
private Cache<String, Object> cache;
private Object delegate;
public NoArgumentsCacheHandler(Object delegate, Duration cacheDuration) {
this.delegate = delegate;
this.cache = CacheBuilder.newBuilder().expireAfterWrite(cacheDuration.toMillis(), TimeUnit.MILLISECONDS).build();
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (args==null || args.length==0) {
return invokeCached(proxy, method);
}
return method.invoke(proxy, args);
}
private Object invokeCached(Object proxy, Method method) throws Exception {
return cache.get(method.getName(), () -> {
return method.invoke(delegate, new Object[] {});
});
}
}

View File

@@ -12,7 +12,6 @@ package org.springframework.ide.vscode.commons.boot.app.cli;
import java.io.IOException;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.time.Duration;
import java.util.Map.Entry;
@@ -20,11 +19,13 @@ import java.util.Properties;
import javax.management.remote.JMXServiceURL;
import org.springframework.ide.vscode.commons.util.MemoizingProxy;
public class RemoteSpringBootApp extends AbstractSpringBootApp {
private String jmxUrl;
private RemoteSpringBootApp(String jmxUrl) {
protected RemoteSpringBootApp(String jmxUrl) {
this.jmxUrl = jmxUrl;
}
@@ -75,14 +76,13 @@ public class RemoteSpringBootApp extends AbstractSpringBootApp {
}
}
} catch (IOException e) {
logger.equals(e);
logger.error("", e);
}
return "Unknown";
}
public static SpringBootApp create(String jmxUrl) {
RemoteSpringBootApp delegate = new RemoteSpringBootApp(jmxUrl);
return (SpringBootApp) Proxy.newProxyInstance(RemoteSpringBootApp.class.getClassLoader(), new Class[] {SpringBootApp.class}, new NoArgumentsCacheHandler(delegate, Duration.ofMillis(4900)));
return MemoizingProxy.create(RemoteSpringBootApp.class, Duration.ofMillis(4900), jmxUrl);
}
}

View File

@@ -10,15 +10,11 @@
*******************************************************************************/
package org.springframework.ide.vscode.commons.boot.app.cli;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import javax.management.remote.JMXConnector;
import org.springframework.ide.vscode.commons.boot.app.cli.livebean.LiveBeansModel;
import org.springframework.ide.vscode.commons.boot.app.cli.requestmappings.RequestMapping;
@@ -38,7 +34,6 @@ public interface SpringBootApp {
List<String> getActiveProfiles();
Optional<List<LiveConditional>> getLiveConditionals() throws Exception;
Properties getSystemProperties() throws Exception;
JMXConnector getJmxConnector() throws MalformedURLException, IOException;
default String getSystemProperty(String string) throws Exception {
Object r = getSystemProperties().get(string);