Spring Boot 如何为静态方法中创建的对象生成Spring Bean
Spring Boot 改造方案
核心改造原则:
- 移除业务类的静态方法,将类交由Spring IoC容器管理,使用依赖注入替代手动
new对象的操作 - 运行时动态生成的参数(比如本次根据命令行参数生成的
Model)不需要注册为Spring Bean,直接作为方法入参传递即可 - 无状态的业务类默认注册为单例Bean即可满足需求
完整改造后代码
1. 启动类改造
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import javax.annotation.Resource; @SpringBootApplication public class TestApplication implements CommandLineRunner { // 注入Spring管理的A类实例 @Resource private A a; public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } @Override public void run(String... args) throws CmdLineException { final CommandLineArgs arguments = new CommandLineArgs(); CmdLineParser parser = new CmdLineParser(arguments); parser.parseArgument(args); // 调用实例方法而非静态方法 a.generatedData(arguments); } }
2. A类改造
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.annotation.Resource; @Component public class A { private static final Logger LOG = LoggerFactory.getLogger(A.class); // 注入Spring管理的B类实例 @Resource private B b; public void generatedData(CommandLineArgs arguments) { LOG.info("Starting visualization."); Model model = createModel(arguments); // 把动态生成的model作为方法参数传入 b.build(model); } private Model createModel(CommandLineArgs arguments) { // 原有逻辑保持不变 ... } }
3. B类改造
import org.springframework.stereotype.Component; @Component public class B { // 调整方法入参接收动态生成的Model,不需要在构造方法传入 public void build(Model model) { // 原有逻辑保持不变,直接使用传入的model即可 ... } }
特殊场景适配(如果B必须在构造时传入Model)
如果原有逻辑要求B实例化时必须传入Model,无法调整为方法入参,可以将B定义为原型Bean,通过ObjectProvider动态创建实例:
调整后的B类
import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class B { // 保留构造方法传入Model public B(Model model) { // 原有构造逻辑 } public void build() { // 原有逻辑保持不变 ... } }
调整后的A类
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.stereotype.Component; import javax.annotation.Resource; @Component public class A { private static final Logger LOG = LoggerFactory.getLogger(A.class); // 注入B的实例提供者,支持动态带参创建原型Bean @Resource private ObjectProvider<B> bProvider; public void generatedData(CommandLineArgs arguments) { LOG.info("Starting visualization."); Model model = createModel(arguments); // 传入动态生成的model创建B实例 B b = bProvider.getObject(model); b.build(); } private Model createModel(CommandLineArgs arguments) { // 原有逻辑保持不变 ... } }
内容的提问来源于stack exchange,提问作者user1298426
相关产品推荐
相关产品推荐

