Spring Boot和JFinal的主方法构造函数被调用两次的问题!!!

这里举一个例子,是spring boot的,JFinal是一个道理和一样的解决办法。

1:Spring Boot的事物增强。

先看代码:

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.swing.*;

@SpringBootApplication
public class DemoApplication {

    public DemoApplication() {
        System.out.println("im constructor");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DemoApplication();
                createAndShowGUI();
            }
        });
        SpringApplication.run(DemoApplication.class, args);
    }

    private static void createAndShowGUI() {
        System.out.println("im static");
    }
}

执行结果:

im constructor
im static

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.6.RELEASE)

2019-08-04 14:29:55.249  INFO 1160 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication on PC-20170518JWLD with PID 1160 (C:\Users\Administrator\Desktop\demo\target\classes started by Administrator in C:\Users\Administrator\Desktop\demo)
2019-08-04 14:29:55.254  INFO 1160 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
im constructor
2019-08-04 14:29:56.374  INFO 1160 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.798 seconds (JVM running for 2.683)

分析:可以看到构造方法被执行了两次,但是静态方法是正常的只被执行了一次。在来看下是谁调用了两次构造方法。

添加打印方法。为了避免报错引起程序中断加上try catch。再次执行。

 public DemoApplication() {
        try{
            Thread.dumpStack();//打印调用栈
        }catch (Exception e){
            
        }
        System.out.println("im constructor");
    }

输出:

java.lang.Exception: Stack trace
	at java.lang.Thread.dumpStack(Thread.java:1336)
	at com.example.demo.DemoApplication.<init>(DemoApplication.java:13)
	at com.example.demo.DemoApplication$1.run(DemoApplication.java:25)
	at java.awt.event.InvocationEvent.dispatch$$$capture(InvocationEvent.java:311)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
	at java.awt.EventQueue.access$500(EventQueue.java:97)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.awt.EventQueue$3.run(EventQueue.java:703)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
im constructor
im static

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.6.RELEASE)

2019-08-04 14:36:24.443  INFO 9152 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication on PC-20170518JWLD with PID 9152 (C:\Users\Administrator\Desktop\demo\target\classes started by Administrator in C:\Users\Administrator\Desktop\demo)
2019-08-04 14:36:24.452  INFO 9152 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
java.lang.Exception: Stack trace
	at java.lang.Thread.dumpStack(Thread.java:1336)
	at com.example.demo.DemoApplication.<init>(DemoApplication.java:13)
	at com.example.demo.DemoApplication$$EnhancerBySpringCGLIB$$88aee20c.<init>(<generated>)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:172)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1295)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1197)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:742)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:389)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:311)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202)
	at com.example.demo.DemoApplication.main(DemoApplication.java:30)im constructor

2019-08-04 14:36:25.599  INFO 9152 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 2.063 seconds (JVM running for 3.578)
Disconnected from the target VM, address: '127.0.0.1:53365', transport: 'socket'

可以看到是

new DemoApplication();
SpringApplication.run(DemoApplication.class, args);

这两个方法的调用。先来说解决办法再说引起的原因。

先说第一个解决办法:既然知道构造方法被执行了两次,也知道执行了顺序了,就可以加个全局变量,运行一次后再运行就跳出。代码如下。

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.swing.*;

@SpringBootApplication
public class DemoApplication {

    public static boolean OPEN = true;

    public DemoApplication() {
        if (!OPEN){
            return;
        }
        OPEN = false;
        System.out.println("im constructor");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DemoApplication();
                createAndShowGUI();
            }
        });
        SpringApplication.run(DemoApplication.class, args);
    }

    private static void createAndShowGUI() {
        System.out.println("im static");
    }
}

再看下执行结果:

im constructor
im static

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.6.RELEASE)

2019-08-04 14:43:53.563  INFO 8300 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication on PC-20170518JWLD with PID 8300 (C:\Users\Administrator\Desktop\demo\target\classes started by Administrator in C:\Users\Administrator\Desktop\demo)
2019-08-04 14:43:53.567  INFO 8300 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2019-08-04 14:43:54.691  INFO 8300 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.757 seconds (JVM running for 2.616)

噔噔·······,只执行了一次,简单粗暴,哈哈。而且执行成功也是被new才执行的。下面说说,SpringApplication.run(DemoApplication.class, args);这个方法。先看上边的调用栈,,看看这个方法怎么调用的。

这里我先看了Spring Boot的启动流程这篇文章。

简单一句话就是:这个方法里面首先要创建一个SpringApplication对象实例(如果已创建则去执行。),然后调用这个创建好的SpringApplication的实例方法。

第二个办法:既然SpringApplication的构造函数会被执行两次,那就再写个类,去调用就好了。

第三个办法就是,写静态方法了。。。。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值