Spring 全局 Bean 注入

61 阅读1分钟

引用 全局 Bean 注入 | TaoPanfeng's Blog

此篇文章

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 注入

使用效果

image.png

工具类

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();
    }
}