Java应用中@Inject注入FactoryA为何返回null?
问题分析:主类中
factoryA为null的原因 核心原因1:DI框架不支持静态字段注入
不管是CDI(Contexts and Dependency Injection)还是Spring这类依赖注入框架,都不会自动注入静态字段。DI的设计目标是管理实例对象的依赖关系,静态字段属于类本身,不属于任何实例,因此不在DI容器的管理范畴内,容器不会主动为静态字段赋值。
核心原因2:主类未被DI容器初始化
Parent类加了@Named注解,但main方法是Java程序的静态入口,执行时JVM直接调用这个静态方法,并不会触发DI容器去创建Parent的实例。只有当DI容器负责创建类的实例时,才会处理类中的@Inject注解,完成依赖注入。而这里Parent的实例根本没被容器创建,自然不会有任何注入操作。
额外问题:实例字段myMap在静态方法中也未初始化
顺带提一句,main方法里直接使用的myMap是Parent的实例字段,静态方法中直接访问时也会是null,因为此时没有Parent的实例,实例字段也未被初始化。
修正方案示例
如果要让依赖注入生效,需要让DI容器接管对象的创建和管理,同时避免使用静态字段注入。以下是调整后的示例:
@Named class Parent { @Inject private FactoryA factoryA; // 改为实例字段 private Map<String, String> myMap; public static void main(String[] args) { // 初始化DI容器(以CDI为例,不同容器初始化方式不同) SeContainerInitializer initializer = SeContainerInitializer.newInstance(); try (SeContainer container = initializer.initialize()) { // 从容器中获取Parent的实例 Parent parent = container.select(Parent.class).get(); // 初始化myMap parent.myMap = new HashMap<>(); parent.myMap.put("PARAM", "CHILDA"); // 调用方法 Child child = parent.factoryA.getChild(parent.myMap); } } }
@Named public class FactoryA { @Inject @Named("childA") private Child childA; @Inject @Named("childB") private Child childB; public Child getChild(Map<String, String> myMap) { if ("CHILDA".equals(myMap.get("PARAM"))) { // 避免空指针,优先用常量调用equals return childA; } else { return childB; } } }
内容的提问来源于stack exchange,提问作者Aditya Mahajan
相关产品推荐
相关产品推荐

