Skip to content

ApplicationContextUtils Spring上下文工具

cn.com.digitalhainan.tools.spring.ApplicationContextUtils

功能简介

ApplicationContextUtils 提供在非 Spring 管理的类中获取 Spring 上下文、Bean 实例以及发布应用事件的功能,实现普通类与 Spring 容器的交互。

核心方法

方法参数返回值说明
getContext()ApplicationContext获取 Spring 应用上下文
setContext(ApplicationContext)applicationContext: 上下文void手动设置上下文(测试用)
publishEvent(ApplicationEvent event)event: 应用事件void发布应用事件

代码示例

获取 Bean 实例

java
import cn.com.digitalhainan.tools.spring.ApplicationContextUtils;
import org.springframework.context.ApplicationContext;

public class BeanUtil {
    
    /**
     * 根据类型获取 Bean
     */
    public static <T> T getBean(Class<T> clazz) {
        return ApplicationContextUtils.getContext().getBean(clazz);
    }
    
    /**
     * 根据名称获取 Bean
     */
    public static Object getBean(String name) {
        return ApplicationContextUtils.getContext().getBean(name);
    }
    
    /**
     * 根据名称和类型获取 Bean
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return ApplicationContextUtils.getContext().getBean(name, clazz);
    }
}

在非 Spring 类中使用

java
import cn.com.digitalhainan.tools.spring.ApplicationContextUtils;

// 普通类(非 Spring 管理)
public class LegacyService {
    
    public void doSomething() {
        // 获取 UserService Bean
        UserService userService = ApplicationContextUtils.getContext()
            .getBean(UserService.class);
        
        // 调用 Spring 管理的 Service 方法
        User user = userService.getById(1L);
        
        // 业务处理...
    }
}

获取配置属性

java
import cn.com.digitalhainan.tools.spring.ApplicationContextUtils;
import org.springframework.core.env.Environment;

public class ConfigUtil {
    
    /**
     * 获取配置项
     */
    public static String getProperty(String key) {
        Environment env = ApplicationContextUtils.getContext()
            .getEnvironment();
        return env.getProperty(key);
    }
    
    /**
     * 获取配置项(带默认值)
     */
    public static String getProperty(String key, String defaultValue) {
        Environment env = ApplicationContextUtils.getContext()
            .getEnvironment();
        return env.getProperty(key, defaultValue);
    }
}

// 使用示例
String appName = ConfigUtil.getProperty("spring.application.name");
String timeout = ConfigUtil.getProperty("http.timeout", "5000");

发布应用事件

java
import cn.com.digitalhainan.tools.spring.ApplicationContextUtils;
import org.springframework.context.ApplicationEvent;

// 定义事件
public class OrderCreatedEvent extends ApplicationEvent {
    private final Long orderId;
    private final Long userId;
    
    public OrderCreatedEvent(Object source, Long orderId, Long userId) {
        super(source);
        this.orderId = orderId;
        this.userId = userId;
    }
    
    // getter...
}

// 发布事件
@Service
public class OrderService {
    
    public void createOrder(OrderDTO dto) {
        // 保存订单...
        Long orderId = orderMapper.insert(dto);
        
        // 发布订单创建事件
        OrderCreatedEvent event = new OrderCreatedEvent(this, orderId, dto.getUserId());
        ApplicationContextUtils.publishEvent(event);
    }
}

// 监听事件
@Component
public class OrderEventListener {
    
    @EventListener
    public void onOrderCreated(OrderCreatedEvent event) {
        // 发送通知、更新统计等...
        System.out.println("订单 " + event.getOrderId() + " 已创建");
    }
}

检查上下文状态

java
import cn.com.digitalhainan.tools.spring.ApplicationContextUtils;
import org.springframework.context.ApplicationContext;

public class ContextUtil {
    
    /**
     * 检查上下文是否已加载
     */
    public static boolean isContextReady() {
        return ApplicationContextUtils.getContext() != null;
    }
    
    /**
     * 获取应用名称
     */
    public static String getApplicationName() {
        ApplicationContext ctx = ApplicationContextUtils.getContext();
        if (ctx != null) {
            return ctx.getApplicationName();
        }
        return null;
    }
    
    /**
     * 检查是否为开发环境
     */
    public static boolean isDev() {
        ApplicationContext ctx = ApplicationContextUtils.getContext();
        if (ctx != null) {
            String[] profiles = ctx.getEnvironment().getActiveProfiles();
            for (String profile : profiles) {
                if ("dev".equals(profile)) {
                    return true;
                }
            }
        }
        return false;
    }
}

单元测试中使用

java
import cn.com.digitalhainan.tools.spring.ApplicationContextUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class LegacyServiceTest {
    
    @BeforeEach
    public void setup() {
        // 创建测试上下文
        ApplicationContext context = new AnnotationConfigApplicationContext(
            TestConfig.class
        );
        
        // 手动设置上下文
        ApplicationContextUtils.setContext(context);
    }
    
    @Test
    public void testDoSomething() {
        LegacyService service = new LegacyService();
        service.doSomething();
        // 验证...
    }
}

注意事项

  1. 初始化时机:ApplicationContextUtils 通过 ApplicationContextAware 自动注入上下文,确保在 Spring 初始化完成后使用
  2. 空指针检查:在应用启动完成前调用 getContext() 可能返回 null,建议做空值检查
  3. 循环依赖:通过工具类获取 Bean 时要避免循环依赖问题
  4. 测试环境:单元测试中需要手动设置上下文或使用 @SpringBootTest
  5. 设计建议:优先使用依赖注入,工具类作为在无法注入时的备选方案
  6. 线程安全:ApplicationContext 是线程安全的,可以在多线程环境中使用

Power By 数字海南