Featured image of post java错误汇总

java错误汇总

本文阅读量

常见错误汇总

1、循环引用

需求

在mqtt协议完成客户端注册的时候,自动监控一个主题topic/#,方便接收所有的mqtt协议信息,然后根据对应的主题完成信息的处理。

原始代码

MqttConfig:mqtt协议的配置文件,并完成客户端的注册

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Data
@Configuration
@ConfigurationProperties(prefix = "mqtt")
public class MqttConfig {
    // MQTT服务地址
    private String host;
    // 用户名
    private String username;
    // 密码
    private String password;
    // 客户端id
    private String clientId;
    // 监控主题
    private String monitorTopic; "topic/#"
    // 流量控制主题
    private String conFlowTopic;
    // 流量实时显示
    private String realFlowTopic;

  
    @Bean
    public IMqttAsyncClient mqttClient(MqttServiceImpl mqttService) throws MqttException {
        IMqttAsyncClient client = new MqttAsyncClient(host, clientId);
        // ...连接配置
      	MqttConnectOptions options = new MqttConnectOptions();
        options.setUserName(username);
        options.setPassword(password.toCharArray());
        options.setAutomaticReconnect(true);
        options.setConnectionTimeout(10);
      	// 处理接收消息
        client.setCallback(new MqttCallback() {
            @Override
            public void messageArrived(String topic, MqttMessage message) {
                mqttService.handleMessage(topic, message); // 委托给Service处理
            }
            // ...其他回调方法
        });
      
        // 订阅监控主题
        client.subscribe(monitorTopic, 1);
        return client;
    }
}

MqttServiceImpl:主要定于

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Slf4j
@Service
public class MqttServiceImpl implements MqttService {

    @Autowired
    private IMqttAsyncClient mqttClient;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private DeviceService deviceService;

    @Override
    public void subscribe(String topic, int qos) throws MqttException{
        mqttClient.subscribe(topic, qos, (t, msg) -> {
            handleMessage(t, msg); // 复用统一处理逻辑
        });
    }

    // 处理接收到的mqtt消息
    public void handleMessage(String topic, MqttMessage message) {
        String payload = new String(message.getPayload());
        log.info("全局收到 {} 消息: {}", topic, payload);

        // 如果是监控主题消息,执行设备插入逻辑
        if(topic.equals(monitorTopic)) {
            Gson gson = new Gson();
            Map<String, Object> map = gson.fromJson(payload, 
                new TypeToken<Map<String, Object>>(){}.getType());
            if(map.containsKey("imei")) {
                insertDevice((String) map.get("imei"));
            }
        }
    }
  	// 其他方法..
}

我们发现MqttServiceImpl中引用了IMqttAsyncClient即:MqttConfig,而MqttConfig中又引入了MqttServiceImpl,这就发生了循环引用

解决方案1:使用Setter/方法注入(推荐)

1
2
3
4
5
6
7
8
9
@Configuration
public class MqttConfig {
    @Bean
    public IMqttAsyncClient mqttClient() throws MqttException {
        IMqttAsyncClient client = new MqttAsyncClient(host, clientId);
        // ...连接配置
        return client; // 先不设置回调
    }
}

MqttServiceImpl

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Service 
public class MqttServiceImpl implements ApplicationContextAware {
    private IMqttAsyncClient mqttClient;

    @Override
    public void setApplicationContext(ApplicationContext ctx) {
        this.mqttClient = ctx.getBean(IMqttAsyncClient.class);
        mqttClient.setCallback(new MqttCallback() {
            @Override
            public void connectionLost(Throwable cause) {
                System.err.println("MQTT连接断开: " + cause.getMessage());
            }

            @Override
            public void messageArrived(String topic, MqttMessage message) {
                handleMessage(topic, message); // 委托给Service处理
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {}
        });
    }
}

方案2:使用@Lazy延迟加载

1
2
3
4
5
6
7
8
9
@Configuration
public class MqttConfig {
    @Bean
    public IMqttAsyncClient mqttClient(@Lazy MqttService mqttService) throws MqttException {
        IMqttAsyncClient client = new MqttAsyncClient(host, clientId);
        client.setCallback(msg -> mqttService.handleMessage(msg));
        return client;
    }
}

只需要加载@Lazy即可

方案3:进行业务拆分

1
this is php code
这是测试内容2
使用 Hugo 构建
主题 StackJimmy 设计