package com.github.ompc.greys.core.command; import com.github.ompc.greys.core.advisor.Enhancer; import com.github.ompc.greys.core.command.annotation.Cmd; import com.github.ompc.greys.core.manager.ReflectManager; import com.github.ompc.greys.core.server.Session; import com.github.ompc.greys.core.util.LogUtil; import com.github.ompc.greys.core.util.affect.EnhancerAffect; import com.github.ompc.greys.core.util.affect.RowAffect; import com.github.ompc.greys.core.util.matcher.ClassMatcher; import com.github.ompc.greys.core.util.matcher.PatternMatcher; import org.slf4j.Logger; import java.lang.instrument.Instrumentation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import static com.github.ompc.greys.core.util.matcher.PatternMatcher.Strategy.WILDCARD; import static org.apache.commons.lang3.reflect.FieldUtils.getField; /** * 关闭命令 * Created by oldmanpushcart@gmail.com on 14/10/23. */ @Cmd(name = "shutdown", sort = 11, summary = "Shut down Greys server and exit the console", eg = { "shutdown" }) public class ShutdownCommand implements Command { private final Logger logger = LogUtil.getLogger(); private final ReflectManager reflectManager = ReflectManager.Factory.getInstance(); /* * 从GreysClassLoader中加载Spy */ private Class<?> loadSpyClassFromGreysClassLoader(final ClassLoader greysClassLoader, final String spyClassName) { try { return greysClassLoader.loadClass(spyClassName); } catch (ClassNotFoundException e) { logger.warn("Spy load failed from GreysClassLoader, that is impossible!", e); return null; } } /* * 重置agent的greys * 让下载重新加载greys的时候能重新初始化ClassLoader */ private void reset() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { // 从GreysClassLoader中加载Spy final Class<?> spyClassFromGreysClassLoader = loadSpyClassFromGreysClassLoader( ShutdownCommand.class.getClassLoader(), "com.github.ompc.greys.agent.Spy" ); if (null != spyClassFromGreysClassLoader) { // 重置整个greys final Method agentResetMethod = (Method) getField(spyClassFromGreysClassLoader, "AGENT_RESET_METHOD").get(null); agentResetMethod.invoke(null); } } /* * 重置所有已经加载到JVM的Spy */ private void cleanSpy() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { for (final Class<?> spyClass : reflectManager.searchClass(new ClassMatcher(new PatternMatcher(WILDCARD, "com.github.ompc.greys.agent.Spy")))) { final Method cleanMethod = spyClass.getMethod("clean"); cleanMethod.invoke(null); } } @Override public Action getAction() { return new RowAction() { @Override public RowAffect action(Session session, Instrumentation inst, Printer printer) throws Throwable { // 退出之前需要重置所有的增强类 // 重置之前增强的类 final EnhancerAffect enhancerAffect = Enhancer.reset(inst); // reset for agent ClassLoader reset(); // cleanSpy the spy cleanSpy(); printer.println("Greys Server is shut down.").finish(); return new RowAffect(enhancerAffect.cCnt()); } }; } }