关于策略模式的注入问题

博客主要讲述在Java实现策略方法时出现null的问题,经排查是接口实现有多个,需添加别名解决。注入时添加@Qeualifier指定名称,测试类中不用new具体行为策略,注入加别名即可,qualifier填写具体实现的行为策略名称。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
上面抄别人的
当在实现策略方法时,报null,排查后发现是接口实现有多个,需要添加别名

注入时添加@Qeualifier,指定名称,如下图;如图上修改, 测试类中不用new具体行为策略了,注入+别名即可。
在这里插入图片描述

在这里插入图片描述
qualifier中填写为具体实现的行为策略所起的名称,如下
在这里插入图片描述

### 策略模式注入对象为null问题及解决方案 在策略模式的实现过程中,如果使用依赖注入(如Spring框架中的`@Autowired`或`@Inject`),可能会遇到注入对象为`null`的情况。这通常是因为容器未能正确识别或初始化策略类实例。以下是解决该问题的具体方法和分析: #### 1. 使用Spring容器管理策略类 确保所有策略类被Spring容器管理,可以通过在每个具体策略类上添加`@Component`注解来实现[^4]。例如: ```java @Component public class ConcreteStrategyA implements Strategy { @Override public void strategyMethod() { System.out.println("执行具体策略A!"); } } ``` 这样,Spring会自动扫描并注册这些策略类为Bean。 #### 2. 创建策略工厂并注入所有策略 为了减少客户端直接管理多个策略类的复杂度,可以创建一个策略工厂类,并通过依赖注入将所有策略类注入到工厂中[^2]。示例如下: ```java @Component public class StrategyFactory { private final Map<String, Strategy> strategyMap; @Autowired public StrategyFactory(List<Strategy> strategies) { this.strategyMap = strategies.stream() .collect(Collectors.toMap(Strategy::getKey, strategy -> strategy)); } public Strategy getStrategy(String key) { return strategyMap.get(key); } } ``` 在此代码中,`List<Strategy>`通过Spring的构造函数注入机制自动获取所有实现了`Strategy`接口的Bean。每个具体策略类需要实现`getKey`方法以返回唯一的标识符。 #### 3. 避免手动实例化策略类 手动使用`new`关键字实例化策略类会导致Spring无法对其进行管理,从而导致注入失败。因此,应始终依赖Spring容器来实例化和管理Bean。 #### 4. 检查配置文件和组件扫描路径 确保Spring的组件扫描路径涵盖了所有策略类所在的包。如果未正确配置扫描路径,可能导致策略类未被注册为Bean。可以在`@SpringBootApplication`或`@ComponentScan`注解中明确指定扫描路径[^3]: ```java @SpringBootApplication(scanBasePackages = {"com.example.strategies"}) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` #### 5. 使用`@Lazy`延迟加载 如果某些策略类在应用启动时不需要立即加载,可以为其添加`@Lazy`注解以延迟加载,避免因依赖关系导致的注入失败[^4]。 ```java @Component @Lazy public class LazyConcreteStrategy implements Strategy { @Override public void strategyMethod() { System.out.println("执行延迟加载策略!"); } } ``` #### 6. 调试与验证 如果仍然遇到注入对象为`null`的问题,可以通过以下方式排查: - 检查是否遗漏了`@Component`或其他必要的注解。 - 确保策略类已被正确注册为Spring Bean,可以通过打印`ApplicationContext`中的Bean名称列表进行验证。 ```java @Autowired private ApplicationContext context; public void printBeans() { String[] beanNames = context.getBeanDefinitionNames(); Arrays.stream(beanNames).forEach(System.out::println); } ``` --- ### 示例代码 以下是一个完整的策略模式实现示例,结合Spring依赖注入解决注入对象为`null`的问题: ```java // 策略接口 public interface Strategy { String getKey(); void execute(); } // 具体策略A @Component public class ConcreteStrategyA implements Strategy { @Override public String getKey() { return "strategyA"; } @Override public void execute() { System.out.println("执行具体策略A!"); } } // 具体策略B @Component public class ConcreteStrategyB implements Strategy { @Override public String getKey() { return "strategyB"; } @Override public void execute() { System.out.println("执行具体策略B!"); } } // 策略工厂 @Component public class StrategyFactory { private final Map<String, Strategy> strategyMap; @Autowired public StrategyFactory(List<Strategy> strategies) { this.strategyMap = strategies.stream() .collect(Collectors.toMap(Strategy::getKey, strategy -> strategy)); } public Strategy getStrategy(String key) { return strategyMap.get(key); } } // 客户端调用 @Service public class ClientService { @Autowired private StrategyFactory strategyFactory; public void performStrategy(String key) { Strategy strategy = strategyFactory.getStrategy(key); if (strategy != null) { strategy.execute(); } else { System.out.println("未找到对应的策略!"); } } } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值