此篇文章
2026-01-23 16:21:45 今天在此站看到了一篇帖子 Spring 项目别再乱注入 Service 了!用 Lambda 封装个统一调用组件,爽到飞起兄弟们,咱做 Sprin - 掘金 用法不友好,多个参数很难去传参。
想到了之前,我写的一篇文章,搬运过来,供大家评价!
前言
1、每个类都注入的一大堆的 Bean
2、依赖循环问题 还要手动 spring.main.allow-circular-references=true
3、对于构造器注入,即使开启了依赖循环,仍注入失败,被迫使用 @Lazy + @Autowired
4、想使用依赖静态注入,SpringUtil.getBean(OrgUserRelationService.class); 来获取,获取实现 InitializingBean 来静态注入
--------------------------------
解决思路:
1、封装工具类,使用 $ 符号做为类名
2、一键注入所有的 Bean,(公共 + 静态)
3、后续新的 Bean --- [1] 添加全局变量, [2] 记得 afterPropertiesSet 注入
使用效果
工具类
package com.bozhi.xiaoluo.modules.user;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.bozhi.xiaoluo.modules.common.sensitive.BaiduService;
import com.bozhi.xiaoluo.modules.common.service.AccusationInfoService;
import com.bozhi.xiaoluo.modules.message.config.ChatProperties;
import com.bozhi.xiaoluo.modules.message.service.ChatMessageService;
import com.bozhi.xiaoluo.modules.post.service.ChooseInfoService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.locks.LockSupport;
import java.util.stream.Collectors;
/**
* Spring Bean 静态调用工具类
*
* <pre>
* $.userInfoService.updateUserLevelScore();
*
* UserInfoEntity user = $.userInfoService.getById(3439L);
* </pre>
*/
@Component
public class $ implements InitializingBean {
public static AccusationInfoService accusationInfoService;
public static BaiduService baiduService;
public static ChatMessageService chatMessageService;
public static ChatProperties chatProperties;
public static ChooseInfoService chooseInfoService;
// ...
@Override
public void afterPropertiesSet() {
accusationInfoService = SpringUtil.getBean(AccusationInfoService.class);
baiduService = SpringUtil.getBean(BaiduService.class);
chatMessageService = SpringUtil.getBean(ChatMessageService.class);
chatProperties = SpringUtil.getBean(ChatProperties.class);
chooseInfoService = SpringUtil.getBean(ChooseInfoService.class);
// ...
}
}
// 生成
// @Component// 解除注释来一键生成
class Generate$ implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
Console.log("=======================================================================");
List<String> beanNames = SpringUtil.getBeanFactory().getBeansOfType(Object.class).values().stream()
// [1] 包名过滤
.filter(bean -> bean.getClass().getName().contains("bozhi"))
// [2] 获取 beanName
.map(bean -> bean.getClass().getSimpleName().split("\$\$")[0].replace("Impl", ""))
// [3] 过滤含有这些名称的 beanName
.filter(beanName -> !containsAnyIgnoreCase(beanName,
"NoteInfoNewService", "ItemBasedCacheService", "jpush", "KafkaConsumer",
"RedisConfig", "RedissonConfig", "SchedulerConfig", "TransactionConfig", "MybatisPlusConfig", "DbTxBroker", "ComboTransaction", "AsyncContextAopConfig",
"xiaoluo", "controller", "dao", "token", "filter", "job", "listen", "exception", "$"
))
.filter(StrUtil::isNotBlank)
.collect(Collectors.toList());
// [4] 手动添加 && 排序
beanNames.addAll(CollUtil.newArrayList(
"MongoTemplate", "RedissonClient", "WxMpService"
));
beanNames.sort(Comparator.naturalOrder());
// [5] 生成:全局变量
beanNames.forEach(beanName -> Console.log(" public static {} {};", beanName, StrUtil.lowerFirst(beanName)));
// [6] 生成:变量注入
Console.log(" @Override");
Console.log(" public void afterPropertiesSet() {");
beanNames.forEach(beanName -> Console.log(" {} = SpringUtil.getBean({}.class);", StrUtil.lowerFirst(beanName), beanName));
Console.log(" }");
// [7] 无限阻塞
Console.log("=======================================================================");
Console.log("$ 生成完成,项目启动将无限阻塞");
Console.log("=======================================================================");
LockSupport.park();
}
}