undertow.devMode=true 的时候,会导致单例失效

undertow.devMode=true 的时候,会导致单例失效,创建两个对象

代码信息如下

单例对象

public enum LocalManager {

    INSTANCE;

    private final Map<String, Body> personMap = new ConcurrentHashMap<>();
    private final OrganDataBasket<DataBean> dataBasket = new OrganDataBasket<>();

    public void addPerson(Body body) {
        personMap.put(body.getName(), body);
        System.out.println(body);
        System.out.println(personMap.size());
    }

    public Body findBody(String name) {
        return personMap.get(name);
    }
 }


Controller

@Path(value = "/", viewPath = "/index")
public class LocalController extends Controller {

    public void index() {
        Body body = LocalManager.INSTANCE.findBody("tai2");
        List<MsgParam> allMsg = body.getBrain().getAllMsg();
        set("allMsg", allMsg);
        render("index.html");
    }
}


启动代码

public class SmallLauncher {

    public static void main(String[] args) {
        Body tai2 = new Body("tai2",false);
        LocalManager.INSTANCE.addPerson(tai2);
        UndertowServer.start(LocalConfig.class);
    }

}


undertow.devMode=true 的时候,会导致创建两个LocalManager对象

PH6Z3{UQO2P@]6F%4R`C]H2.png

AVISUCD1[LON{M{4LZF(]2K.png


undertow.devMode=fale 的时候,只会创建一个LocalManager对象

`L]{0`}D_IQ6}F]7SHCDDLN.png

R5ZEFQ`AJGA(P_U(34Z3]`R.png


可以确定是开启热部署 HotswapWatcher功能引起的

还望波总关注一下

评论区

JFinal

2024-02-02 23:57

启动类的 main 方法中除了放启动代码之外,不要放任何其它代码,因为 main 方法中的代码执行时 classloader 是 JVM 默认的,而 UndertowServer.start(...) 启动后才会切到 jfinal undertow 自定义的 HotswapClassloader

将 LocalManager 那段代码想办法挪到项目内部的某个地方调用

JFinal

2024-02-03 00:02

如果一定要在 main 方法放启动之外的代码,可以使用一下 addSystemClassPrefix 方法将那些相关的 class 通过系统级 classLoader 来加载,大致这么玩:

UnsertowServer.create(...).addSystemClassPrefix("xxx.yyy.LocalManager").start();

杜福忠

2024-02-03 12:38

项目配置类就统一放在 JFinalConfig的子类configConstant方法里加载,方便大家协同开发
https://jfinal.com/doc/2-2

badouyuren

2024-02-03 13:28