第1步,创建TaskProcess,代码如下
package cn.xxx.xxxx;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import java.util.HashMap;
import java.util.Map;
public class TaskProcess extends Thread {
private static final Log logger = LogFactory.getLog(TaskProcess.class);
// 获取应用程序上下文环境,用于获取注入bean
private ApplicationContext appCon;
// 线程执行期间内存map
static Map<String,String> processMap = new HashMap<String,String>();
public TaskProcess(ApplicationContext con) {
this.appCon = con;
}
public void run() {
logger.info("线程启动。");
long n=1;
while(true){
logger.info("线程第"+n+"次运行");
processPunction(n);
n++;
try {
//30秒执行1次
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void processPunction(long n) {
try {
//TODO
//XXXMapper xxxMapper= (XXXMapper)appCon.getBean("xx.xx.xxxMapper");
//List list = XXXMapper.select();
//processMap.put(String.valueOf(n), list);
logger.info("业务逻辑。。。。");
processMap.put(String.valueOf(n),"线程第"+n+"次运行");
} catch (Exception e) {
e.printStackTrace();
}
}
}
第2步,创建 TaskManagerMBean,代码如下
package cn.xxx.xxxx;
public interface TaskManagerMBean{
public void startNewProcess();
public void restartProcess();
public void showAliveProcess();
}
第3步,创建TaskManagerMBean的实现类TaskManager,代码如下
package cn.xxx.xxxx;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import java.util.Map;
/**
* jmx监控TaskProcess
*/
public class TaskManager implements TaskManagerMBean{
private static final Log logger = LogFactory.getLog(TaskManager.class);
private ApplicationContext con;
private TaskProcess process;
public TaskManager(ApplicationContext con , TaskProcess process ){
this.con = con;
this.process=process;
}
//启动新的线程
public void startNewProcess() {
if(!process.isAlive()){
logger.info("启动新的线程。");
process = new TaskProcess(con);
process.start();
long processId = process.getId();
logger.info("线程--"+processId+"已启动。");
}else{
logger.info("线程已存在,请先停止原有线程");
}
}
//重启
public void restartProcess() {
logger.info("停止原有线程中。。。");
long processId = process.getId();
process.stop();
logger.info("线程--"+processId+"已停止");
logger.info("重新启动线程中。。。");
process = new TaskProcess(con);
process.start();
processId = process.getId();
logger.info("已重新启动线程--"+processId);
}
//查看活的线程以及业务逻辑中有什么
public void showAliveProcess(){
if(process.isAlive()){
long processId = process.getId();
logger.info("线程--"+processId+"正常。");
Map<String, String> processMap = process.processMap;
logger.info("processMap--"+processMap);
}else{
logger.info("线程不存在");
}
}
}
第4步,创建上下文TaskServletContextContext,代码参考如下
package cn.xxx.xxxx;
import javax.servlet.ServletContext;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
public class TaskServletContextContext implements ApplicationContextAware {
private static ApplicationContext springContext;
public static ApplicationContext getApplicationContext() {
return springContext;
}
public void setServletContext(ServletContext servletContext) {
springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
}
public static void setApplicationContext(WebApplicationContext context) {
springContext = context;
}
public void setAttribute(String name, Object bean) {
if ((springContext instanceof WebApplicationContext))
((WebApplicationContext)springContext).getServletContext().setAttribute(name, bean);
}
public void destroy() throws Exception {
springContext = null;
}
public void setApplicationContext(ApplicationContext arg0)
throws BeansException {
springContext = arg0;
}
}
第6步,创建随服务启动的Listener,代码参考如下
package cn.xxx.xxxx;
import javax.management.*;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletContextEvent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import java.lang.management.ManagementFactory;
public class TaskServletContextListener implements ServletContextListener{
private static final Log logger = LogFactory.getLog(TaskServletContextListener.class);
@Override
public void contextInitialized(ServletContextEvent sce) {
TaskServletContextContext tscc = new TaskServletContextContext();
tscc.setServletContext(sce.getServletContext());
ApplicationContext con = TaskServletContextContext.getApplicationContext();
TaskProcess process = new TaskProcess (con);
process.start();
//启动jmx监控此线程
startJmx(con,process);
}
public void startJmx(ApplicationContext con ,TaskProcess process){
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
try {
ObjectName name = new ObjectName("taskJmx:name=taskJmx");
server.registerMBean(new TaskManager(con, process), name);
} catch (MalformedObjectNameException e) {
e.printStackTrace();
} catch (NotCompliantMBeanException e) {
e.printStackTrace();
} catch (InstanceAlreadyExistsException e) {
e.printStackTrace();
} catch (MBeanRegistrationException e) {
e.printStackTrace();
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// TODO Auto-generated method stub
}
}
第7步,web项目中web.xml的<web-app>节点增加如下配置上面的listener
<listener> <listener-class>cn.xx.xxxx.TaskServletContextListener</listener-class> </listener>
第8步,启动tomcat,Tomcat版本:apache-tomcat-7.0.103
第9步,执行java安装目录下的jconsole.exe
C:\Java\jdk1.8.0_20\bin\jconsole.exe
第10步,查看mbean,连接到tomcart,可能提示不安全,点"不安全连接"即可
第11步,选择MBean页签,找到第6步代码中的name,展开有操作,点击操作,右边显示按钮。点击方法即可
后台打印log:
2021/09/29 19:53:23 [RMI TCP Connection(10)-127.0.0.1] INFO cn.xxx.xxxx.TaskManager -线程--92正常。
2021/09/29 19:53:23 [RMI TCP Connection(10)-127.0.0.1] INFO cn.xxx.xxxx.TaskManager -processMap--{1=线程第1次运行, 2=线程第2次运行, 3=线程第3次运行, 4=线程第4次运行, 5=线程第5次运行}