如何将带InjectionPoint的Spring prototype Bean注入非Spring管理类
问题原因
你配置的Logger prototype Bean依赖的InjectionPoint参数,仅在Spring原生依赖注入场景(如@Autowired注入、构造函数注入等)下会由Spring自动生成传入。手动调用getBean(Logger.class)时没有对应的注入点上下文,Spring无法识别你需要为哪个类生成Logger实例,因此抛出该错误。
修复方案
方案1:快速适配现有逻辑
直接在SpringApplicationContext工具类中新增指定目标类的Logger获取方法,无需修改原有Spring注入逻辑:
@Component public class SpringApplicationContext implements ApplicationContextAware { private static ApplicationContext context; // 原有方法保留 public static <T extends Object> T getBean(Class<T> beanClass) { return context.getBean(beanClass); } // 新增非Spring类专用的Logger获取方法 public static Logger getLogger(Class<?> targetClass) { return LoggerFactory.getLogger(targetClass); } @Override public void setApplicationContext(ApplicationContext context) throws BeansException { SpringApplicationContext.context = context; } }
非Spring管理类中直接传入当前类获取实例即可:
// 示例:在你自己的非Spring类 public class YourNonSpringClass { private static final Logger LOGGER = SpringApplicationContext.getLogger(YourNonSpringClass.class); }
原有Spring管理类的@Autowired注入Logger的逻辑完全不受影响。
方案2:统一日志获取逻辑(更优)
封装统一的日志工具类,同时兼容Spring管理类和非Spring管理类的使用,逻辑完全对齐:
// 统一日志工具类 public class LogUtils { // 非Spring类调用入口 public static Logger getLogger(Class<?> targetClass) { // 可在这里统一添加你的自定义日志配置逻辑 return LoggerFactory.getLogger(targetClass); } // Spring注入用的Bean配置 @Bean @Scope("prototype") Logger logger(InjectionPoint injectionPoint) { return getLogger(injectionPoint.getMethodParameter().getContainingClass()); } }
使用方式:
- Spring管理类:保持原有
@Autowired注入Logger的方式即可,自动匹配当前类的日志实例 - 非Spring管理类:直接调用
LogUtils.getLogger(YourNonSpringClass.class)获取实例
补充说明
不要尝试手动构造InjectionPoint传入getBean方法,实现成本极高且没有实际收益,上述两种方案都可以100%覆盖需求,性能和使用体验都更优。
内容的提问来源于stack exchange,提问作者Raj Venna
相关产品推荐
相关产品推荐

