最近在写微信机器人框架,经过一周左右的时间,终于搞定了框架的插件开发模式(独立创建插件项目、热拔插、解耦合)。
但是在导入service的时候出现了问题,正常来说直接通过@Autowired
即可导入我们需要的service接口。
@Autowired
private PluginOperate pluginOperate; // 自动注入插件管理器
但是运行插件的时候出现了空指针异常,排查了很久,包括问GPT。然后网上搜了几个小时,一度想要放弃……好在最后终于是解决了。
出现的原因: Spring管理的都是单例(singleton),和多对象相冲突。框架项目启动时初始化,会初始化插件管理器,Spring同时会为其注入service,该对象的service不是null,被成功注入。但是,由于Spring默认管理的是单例,所以只会注入一次service。当插件载入框架并启动,框架端会加载插件提供的服务,但是Spring管理的都是单例,不会给新的对象注入service,所以导致只要是创建新的对象,都不能再注入了。
像controller里面有service,service里面有dao。因为controller,service,dao都有是单例,所以注入时不会报null。但是插件不是单例,所以使用Spring注入一次后,后面的对象就不会再注入了,会报NullException。
像controller里面有service,service里面有dao。因为controller,service,dao都有是单例,所以注入时不会报null。但是插件不是单例,所以使用Spring注入一次后,后面的对象就不会再注入了,会报NullException。
解决方案:
private static PluginOperate pluginOperate;
@Autowired
public void setPluginOperate(PluginOperate pluginOperate) {
SystemPlugin.pluginOperate = pluginOperate;
}
此时即可在插件中调pluginOperate提供的方法,而不再报空指针异常。