mirror of
https://gitee.com/jmix/cuba.git
synced 2024-12-02 19:27:57 +08:00
PL-7643 Hot deployment of Groovy beans does not work
This commit is contained in:
parent
da2988e03a
commit
c2f7c71a91
@ -21,6 +21,7 @@ import com.haulmont.cuba.core.global.Configuration;
|
||||
import com.haulmont.cuba.core.global.GlobalConfig;
|
||||
import com.haulmont.cuba.core.global.Scripting;
|
||||
import com.haulmont.cuba.core.sys.AbstractScripting;
|
||||
import com.haulmont.cuba.core.sys.SpringBeanLoader;
|
||||
import com.haulmont.cuba.core.sys.javacl.JavaClassLoader;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -32,8 +33,8 @@ public class ScriptingClientImpl extends AbstractScripting {
|
||||
private String[] scriptEngineRoots;
|
||||
|
||||
@Inject
|
||||
public ScriptingClientImpl(JavaClassLoader javaClassLoader, Configuration configuration) {
|
||||
super(javaClassLoader, configuration);
|
||||
public ScriptingClientImpl(JavaClassLoader javaClassLoader, Configuration configuration, SpringBeanLoader springBeanLoader) {
|
||||
super(javaClassLoader, configuration, springBeanLoader);
|
||||
scriptEngineRoots = new String[] {
|
||||
configuration.getConfig(GlobalConfig.class).getConfDir()
|
||||
};
|
||||
|
@ -32,8 +32,8 @@ public class ScriptingImpl extends AbstractScripting {
|
||||
private String[] scriptEngineRoots;
|
||||
|
||||
@Inject
|
||||
public ScriptingImpl(JavaClassLoader javaClassLoader, Configuration configuration) {
|
||||
super(javaClassLoader, configuration);
|
||||
public ScriptingImpl(JavaClassLoader javaClassLoader, Configuration configuration, SpringBeanLoader springBeanLoader) {
|
||||
super(javaClassLoader, configuration, springBeanLoader);
|
||||
scriptEngineRoots = new String[] {
|
||||
configuration.getConfig(GlobalConfig.class).getConfDir(),
|
||||
configuration.getConfig(ServerConfig.class).getDbDir()
|
||||
|
@ -22,7 +22,7 @@ import com.haulmont.cuba.core.global.Configuration;
|
||||
import com.haulmont.cuba.core.global.GlobalConfig;
|
||||
import com.haulmont.cuba.core.sys.AppContext;
|
||||
import com.haulmont.cuba.core.sys.CubaDefaultXmlWebApplicationContext;
|
||||
import com.haulmont.cuba.core.sys.javacl.RemotingContextHolder;
|
||||
import com.haulmont.cuba.core.sys.RemotingContextHolder;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.text.StrTokenizer;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -111,8 +111,15 @@ public interface Scripting {
|
||||
*/
|
||||
Class<?> loadClassNN(String name);
|
||||
|
||||
/**
|
||||
* Remove compiled class from cache
|
||||
* @return true if class removed from cache
|
||||
*/
|
||||
boolean removeClass(String name);
|
||||
|
||||
/**
|
||||
* Clears compiled classes cache
|
||||
*/
|
||||
void clearCache();
|
||||
|
||||
}
|
@ -30,8 +30,6 @@ import groovy.util.ResourceConnector;
|
||||
import groovy.util.ResourceException;
|
||||
import groovy.util.ScriptException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.apache.commons.pool2.BaseKeyedPooledObjectFactory;
|
||||
import org.apache.commons.pool2.PooledObject;
|
||||
import org.apache.commons.pool2.impl.DefaultPooledObject;
|
||||
@ -39,6 +37,8 @@ import org.apache.commons.pool2.impl.GenericKeyedObjectPool;
|
||||
import org.apache.commons.pool2.impl.GenericKeyedObjectPoolConfig;
|
||||
import org.codehaus.groovy.control.CompilationFailedException;
|
||||
import org.codehaus.groovy.control.CompilerConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -46,6 +46,7 @@ import java.lang.reflect.Field;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -58,23 +59,21 @@ public abstract class AbstractScripting implements Scripting {
|
||||
|
||||
private static final Pattern IMPORT_PATTERN = Pattern.compile("\\bimport\\b\\s+");
|
||||
private static final Pattern PACKAGE_PATTERN = Pattern.compile("\\bpackage\\b\\s+.+");
|
||||
|
||||
private JavaClassLoader javaClassLoader;
|
||||
|
||||
protected JavaClassLoader javaClassLoader;
|
||||
protected SpringBeanLoader springBeanLoader;
|
||||
protected String groovyClassPath;
|
||||
|
||||
protected Set<String> imports = new HashSet<>();
|
||||
|
||||
protected volatile GroovyScriptEngine gse;
|
||||
|
||||
protected volatile GroovyClassLoader gcl;
|
||||
|
||||
protected volatile CubaGroovyClassLoader gcl;
|
||||
protected GenericKeyedObjectPool<String, Script> pool;
|
||||
|
||||
protected GlobalConfig globalConfig;
|
||||
|
||||
public AbstractScripting(JavaClassLoader javaClassLoader, Configuration configuration) {
|
||||
public AbstractScripting(JavaClassLoader javaClassLoader, Configuration configuration, SpringBeanLoader springBeanLoader) {
|
||||
this.javaClassLoader = javaClassLoader;
|
||||
this.springBeanLoader = springBeanLoader;
|
||||
globalConfig = configuration.getConfig(GlobalConfig.class);
|
||||
groovyClassPath = globalConfig.getConfDir() + File.pathSeparator;
|
||||
|
||||
@ -109,7 +108,7 @@ public abstract class AbstractScripting implements Scripting {
|
||||
return gse;
|
||||
}
|
||||
|
||||
protected GroovyClassLoader getGroovyClassLoader() {
|
||||
protected CubaGroovyClassLoader getGroovyClassLoader() {
|
||||
if (gcl == null) {
|
||||
synchronized (this) {
|
||||
if (gcl == null) {
|
||||
@ -147,10 +146,9 @@ public abstract class AbstractScripting implements Scripting {
|
||||
Matcher packageMatcher = PACKAGE_PATTERN.matcher(key);
|
||||
if (packageMatcher.find()) {
|
||||
StringBuffer s = new StringBuffer();
|
||||
packageMatcher.appendReplacement(s, "$0\n"+sb);
|
||||
packageMatcher.appendReplacement(s, "$0\n" + sb);
|
||||
result = packageMatcher.appendTail(s).toString();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
result = sb.append(key).toString();
|
||||
}
|
||||
}
|
||||
@ -279,6 +277,11 @@ public abstract class AbstractScripting implements Scripting {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeClass(String name) {
|
||||
return getGroovyClassLoader().removeClass(name) || javaClassLoader.removeClass(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCache() {
|
||||
getGroovyClassLoader().clearCache();
|
||||
@ -313,7 +316,7 @@ public abstract class AbstractScripting implements Scripting {
|
||||
// First workaround for invocation from GroovyScriptEngine.isSourceNewer()
|
||||
for (String path : rootPath) {
|
||||
String substrResourceName = resourceName.substring(1);
|
||||
path = path.replace('\\','/');
|
||||
path = path.replace('\\', '/');
|
||||
if (substrResourceName.startsWith(path))
|
||||
resourceName = substrResourceName;
|
||||
if (resourceName.startsWith(path)) {
|
||||
@ -406,6 +409,12 @@ public abstract class AbstractScripting implements Scripting {
|
||||
super(AbstractScripting.this.javaClassLoader, cc);
|
||||
}
|
||||
|
||||
public boolean removeClass(String className) {
|
||||
Class clazz = getClassCacheEntry(className);
|
||||
removeClassCacheEntry(className);
|
||||
return clazz != null;
|
||||
}
|
||||
|
||||
// This overridden method is almost identical to super, but prefers Groovy source over parent classloader class
|
||||
@Override
|
||||
public Class loadClass(String name, boolean lookupScriptFiles, boolean preferClassOverScript, boolean resolve) throws ClassNotFoundException, CompilationFailedException {
|
||||
@ -440,6 +449,7 @@ public abstract class AbstractScripting implements Scripting {
|
||||
removeClassCacheEntry(name);
|
||||
} else {
|
||||
setClassCacheEntry(cls);
|
||||
springBeanLoader.updateContext(Collections.singletonList(cls));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2016 Haulmont.
|
||||
* Copyright (c) 2008-2017 Haulmont.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -12,11 +12,12 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.sys.javacl;
|
||||
package com.haulmont.cuba.core.sys;
|
||||
|
||||
import com.haulmont.cuba.core.global.Scripting;
|
||||
import com.haulmont.cuba.core.sys.javacl.JavaClassLoader;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
@ -26,13 +27,15 @@ import static java.lang.String.format;
|
||||
|
||||
@Component("cuba_ClassLoaderManager")
|
||||
public class ClassLoaderManager implements ClassLoaderManagerMBean {
|
||||
@Inject
|
||||
protected Scripting scripting;
|
||||
@Inject
|
||||
protected JavaClassLoader javaClassLoader;
|
||||
|
||||
@Override
|
||||
public String loadClass(String className) {
|
||||
try {
|
||||
Class<?> aClass = javaClassLoader.loadClass(className);
|
||||
Class<?> aClass = scripting.loadClassNN(className);
|
||||
return format("Loaded %s", aClass.toString());
|
||||
} catch (Exception e) {
|
||||
return ExceptionUtils.getStackTrace(e);
|
||||
@ -42,13 +45,8 @@ public class ClassLoaderManager implements ClassLoaderManagerMBean {
|
||||
@Override
|
||||
public String removeClass(String className) {
|
||||
try {
|
||||
TimestampClass removed = javaClassLoader.compiled.remove(className);
|
||||
if (removed != null) {
|
||||
for (String dependent : removed.dependent) {
|
||||
removeClass(dependent);
|
||||
}
|
||||
}
|
||||
return removed != null ? format("Removed %s", removed.clazz.toString()) : "No such class in cache";
|
||||
boolean removed = scripting.removeClass(className);
|
||||
return removed ? format("Removed %s", className) : "No such class in cache";
|
||||
} catch (Exception e) {
|
||||
return ExceptionUtils.getStackTrace(e);
|
||||
}
|
||||
@ -57,7 +55,7 @@ public class ClassLoaderManager implements ClassLoaderManagerMBean {
|
||||
@Override
|
||||
public String reloadClass(String className) {
|
||||
try {
|
||||
removeClass(className);
|
||||
javaClassLoader.removeClass(className);
|
||||
return loadClass(className);
|
||||
} catch (Exception e) {
|
||||
return ExceptionUtils.getStackTrace(e);
|
||||
@ -67,11 +65,9 @@ public class ClassLoaderManager implements ClassLoaderManagerMBean {
|
||||
@Override
|
||||
public String getClassDependencies(String className) {
|
||||
try {
|
||||
TimestampClass timestampClass = javaClassLoader.compiled.get(className);
|
||||
if (timestampClass != null) {
|
||||
return format("Dependencies \n%s\nDependent \n%s", timestampClass.dependencies, timestampClass.dependent);
|
||||
if (javaClassLoader.isLoadedClass(className)) {
|
||||
return format("Dependencies \n%s\nDependent \n%s", javaClassLoader.getClassDependencies(className), javaClassLoader.getClassDependent(className));
|
||||
}
|
||||
|
||||
return "No such class in cache";
|
||||
} catch (Exception e) {
|
||||
return ExceptionUtils.getStackTrace(e);
|
||||
@ -81,7 +77,7 @@ public class ClassLoaderManager implements ClassLoaderManagerMBean {
|
||||
@Override
|
||||
public String clearCache() {
|
||||
try {
|
||||
javaClassLoader.clearCache();
|
||||
scripting.clearCache();
|
||||
return "Done";
|
||||
} catch (Exception e) {
|
||||
return ExceptionUtils.getStackTrace(e);
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2016 Haulmont.
|
||||
* Copyright (c) 2008-2017 Haulmont.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -12,10 +12,9 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.sys.javacl;
|
||||
package com.haulmont.cuba.core.sys;
|
||||
|
||||
public interface ClassLoaderManagerMBean {
|
||||
String reloadClass(String className) throws ClassNotFoundException;
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2016 Haulmont.
|
||||
* Copyright (c) 2008-2017 Haulmont.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -12,10 +12,9 @@
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.sys.javacl;
|
||||
package com.haulmont.cuba.core.sys;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2017 Haulmont.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.haulmont.cuba.core.sys;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.ManagedBean;
|
||||
import java.util.Collection;
|
||||
|
||||
@Component("cuba_SpringBeanLoader")
|
||||
public class SpringBeanLoader implements BeanFactoryAware {
|
||||
|
||||
protected DefaultListableBeanFactory beanFactory;
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
if (beanFactory instanceof DefaultListableBeanFactory) {
|
||||
this.beanFactory = (DefaultListableBeanFactory) beanFactory;
|
||||
}
|
||||
}
|
||||
|
||||
public void updateContext(Collection<Class> classes) {
|
||||
if (beanFactory != null) {
|
||||
boolean needToRefreshRemotingContext = false;
|
||||
for (Class clazz : classes) {
|
||||
Service serviceAnnotation = (Service) clazz.getAnnotation(Service.class);
|
||||
ManagedBean managedBeanAnnotation = (ManagedBean) clazz.getAnnotation(ManagedBean.class);
|
||||
Component componentAnnotation = (Component) clazz.getAnnotation(Component.class);
|
||||
Controller controllerAnnotation = (Controller) clazz.getAnnotation(Controller.class);
|
||||
|
||||
String beanName = null;
|
||||
if (serviceAnnotation != null) {
|
||||
beanName = serviceAnnotation.value();
|
||||
} else if (managedBeanAnnotation != null) {
|
||||
beanName = managedBeanAnnotation.value();
|
||||
} else if (componentAnnotation != null) {
|
||||
beanName = componentAnnotation.value();
|
||||
} else if (controllerAnnotation != null) {
|
||||
beanName = controllerAnnotation.value();
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(beanName)) {
|
||||
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
|
||||
beanDefinition.setBeanClass(clazz);
|
||||
Scope scope = (Scope) clazz.getAnnotation(Scope.class);
|
||||
if (scope != null) {
|
||||
beanDefinition.setScope(scope.value());
|
||||
}
|
||||
|
||||
beanFactory.registerBeanDefinition(beanName, beanDefinition);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(beanName)) {
|
||||
needToRefreshRemotingContext = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needToRefreshRemotingContext) {
|
||||
ApplicationContext remotingContext = RemotingContextHolder.getRemotingApplicationContext();
|
||||
if (remotingContext != null && remotingContext instanceof ConfigurableApplicationContext) {
|
||||
((ConfigurableApplicationContext) remotingContext).refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -21,26 +21,14 @@ import com.google.common.collect.Multimap;
|
||||
import com.haulmont.cuba.core.global.Configuration;
|
||||
import com.haulmont.cuba.core.global.GlobalConfig;
|
||||
import com.haulmont.cuba.core.global.TimeSource;
|
||||
import com.haulmont.cuba.core.sys.CubaClassPathXmlApplicationContext;
|
||||
import com.haulmont.cuba.core.sys.SpringBeanLoader;
|
||||
import com.haulmont.cuba.core.sys.javacl.compiler.CharSequenceCompiler;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.perf4j.log4j.Log4JStopWatch;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Scope;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.ManagedBean;
|
||||
import javax.inject.Inject;
|
||||
import javax.tools.DiagnosticCollector;
|
||||
import javax.tools.JavaFileObject;
|
||||
@ -55,7 +43,7 @@ import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@Component("cuba_JavaClassLoader")
|
||||
public class JavaClassLoader extends URLClassLoader implements BeanFactoryAware, ApplicationContextAware {
|
||||
public class JavaClassLoader extends URLClassLoader {
|
||||
private static final String JAVA_CLASSPATH = System.getProperty("java.class.path");
|
||||
private static final String PATH_SEPARATOR = System.getProperty("path.separator");
|
||||
private static final String JAR_EXT = ".jar";
|
||||
@ -73,11 +61,10 @@ public class JavaClassLoader extends URLClassLoader implements BeanFactoryAware,
|
||||
protected final ProxyClassLoader proxyClassLoader;
|
||||
protected final SourceProvider sourceProvider;
|
||||
|
||||
protected CubaClassPathXmlApplicationContext applicationContext;
|
||||
protected DefaultListableBeanFactory beanFactory;
|
||||
|
||||
@Inject
|
||||
private TimeSource timeSource;
|
||||
protected TimeSource timeSource;
|
||||
@Inject
|
||||
protected SpringBeanLoader springBeanLoader;
|
||||
|
||||
@Inject
|
||||
public JavaClassLoader(Configuration configuration) {
|
||||
@ -105,21 +92,6 @@ public class JavaClassLoader extends URLClassLoader implements BeanFactoryAware,
|
||||
this.sourceProvider = new SourceProvider(rootDir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
if (beanFactory instanceof DefaultListableBeanFactory) {
|
||||
this.beanFactory = (DefaultListableBeanFactory) beanFactory;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
if (applicationContext instanceof CubaClassPathXmlApplicationContext) {
|
||||
// ((DefaultResourceLoader) applicationContext).setClassLoader(this);
|
||||
this.applicationContext = (CubaClassPathXmlApplicationContext) applicationContext;
|
||||
}
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
compiled.clear();
|
||||
}
|
||||
@ -141,7 +113,7 @@ public class JavaClassLoader extends URLClassLoader implements BeanFactoryAware,
|
||||
CompilationScope compilationScope = new CompilationScope(this, containerClassName);
|
||||
if (!compilationScope.compilationNeeded()) {
|
||||
TimestampClass timestampClass = getTimestampClass(fullClassName);
|
||||
if (timestampClass==null) {
|
||||
if (timestampClass == null) {
|
||||
throw new ClassNotFoundException(fullClassName);
|
||||
}
|
||||
return timestampClass.clazz;
|
||||
@ -172,7 +144,7 @@ public class JavaClassLoader extends URLClassLoader implements BeanFactoryAware,
|
||||
|
||||
clazz = compiledClasses.get(fullClassName);
|
||||
|
||||
updateSpringContext(compiledClasses.values());
|
||||
springBeanLoader.updateContext(compiledClasses.values());
|
||||
|
||||
return clazz;
|
||||
} catch (Exception e) {
|
||||
@ -187,49 +159,34 @@ public class JavaClassLoader extends URLClassLoader implements BeanFactoryAware,
|
||||
}
|
||||
}
|
||||
|
||||
private void updateSpringContext(Collection<Class> classes) {
|
||||
if (beanFactory != null) {
|
||||
boolean needToRefreshRemotingContext = false;
|
||||
for (Class clazz : classes) {
|
||||
Service serviceAnnotation = (Service) clazz.getAnnotation(Service.class);
|
||||
ManagedBean managedBeanAnnotation = (ManagedBean) clazz.getAnnotation(ManagedBean.class);
|
||||
Component componentAnnotation = (Component) clazz.getAnnotation(Component.class);
|
||||
Controller controllerAnnotation = (Controller) clazz.getAnnotation(Controller.class);
|
||||
|
||||
String beanName = null;
|
||||
if (serviceAnnotation != null) {
|
||||
beanName = serviceAnnotation.value();
|
||||
} else if (managedBeanAnnotation != null) {
|
||||
beanName = managedBeanAnnotation.value();
|
||||
} else if (componentAnnotation != null) {
|
||||
beanName = componentAnnotation.value();
|
||||
} else if (controllerAnnotation != null) {
|
||||
beanName = controllerAnnotation.value();
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(beanName)) {
|
||||
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
|
||||
beanDefinition.setBeanClass(clazz);
|
||||
Scope scope = (Scope) clazz.getAnnotation(Scope.class);
|
||||
if (scope != null) {
|
||||
beanDefinition.setScope(scope.value());
|
||||
}
|
||||
|
||||
beanFactory.registerBeanDefinition(beanName, beanDefinition);
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(beanName)) {
|
||||
needToRefreshRemotingContext = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needToRefreshRemotingContext) {
|
||||
ApplicationContext remotingContext = RemotingContextHolder.getRemotingApplicationContext();
|
||||
if (remotingContext != null && remotingContext instanceof ConfigurableApplicationContext) {
|
||||
((ConfigurableApplicationContext) remotingContext).refresh();
|
||||
}
|
||||
public boolean removeClass(String className) {
|
||||
TimestampClass removed = compiled.remove(className);
|
||||
if (removed != null) {
|
||||
for (String dependent : removed.dependent) {
|
||||
removeClass(dependent);
|
||||
}
|
||||
}
|
||||
return removed != null;
|
||||
}
|
||||
|
||||
public boolean isLoadedClass(String className) {
|
||||
return compiled.containsKey(className);
|
||||
}
|
||||
|
||||
public Collection<String> getClassDependencies(String className) {
|
||||
TimestampClass timestampClass = compiled.get(className);
|
||||
if (timestampClass != null) {
|
||||
return timestampClass.dependencies;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public Collection<String> getClassDependent(String className) {
|
||||
TimestampClass timestampClass = compiled.get(className);
|
||||
if (timestampClass != null) {
|
||||
return timestampClass.dependent;
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user