【问题标题】:Unable to Autowire无法自动接线
【发布时间】:2019-01-25 08:08:50
【问题描述】:

使用 Spring Initializer 创建一个简单的 Spring boot。我只在可用选项下选择 DevTools。

创建项目后,无需对其进行任何更改,即可正常运行程序。

现在,当我尝试在项目中进行一些自动装配时,它根本不起作用。我不明白。一直在这里查看以前的问题,这些问题有解决方案,但没有一个有效,而且我在我的情况下所做的事情并不复杂,如下所示。请告知我所缺少的。

@SpringBootApplication
public class DemoApplication {

    //  @Autowired
    //  private static Maker maker; // Stopped using this cos I wanted to check if the autowiring is not working in this class only or anywhere. Turns out it is anywhere. 

        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
            Maker maker = new Maker();
            maker.printName(); // Fails cos of ServiceHelper Autowiring 
        }
    }


@Service
public class Maker {

    @Autowired
    private ServiceHelper serviceHelper;

    public void printName(){
        System.out.println("This is from the method body itself.");
        System.out.println("Auto wiring works cos I got this -> " + serviceHelper.help());
    }
}

@Component
public class ServiceHelper {
    public String help(){
        return "...FROM HELPER...";
    }
}

堆栈跟踪

线程“restartedMain”中的异常 java.lang.reflect.InvocationTargetException 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:497) 在 org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) 引起:java.lang.NullPointerException at com.example.demo.services.Maker.printName(Maker.java:15) 在 com.example.demo.DemoApplication.main(DemoApplication.java:17) ... 5 更多

【问题讨论】:

  • 您不能自动装配静态字段。
  • @DarrenForsythe 我已经注释掉了静态字段。
  • @kang 检查我的答案以解决在静态字段中注入依赖项的工作。

标签: java spring-boot


【解决方案1】:

您自己创建一个实例,它的 ServiceHelper 不会被 Spring 自动装配:

Maker maker = new Maker();

你可以通过ApplicationContext访问bean:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ApplicationContext cts = SpringApplication.run(DemoApplication.class, args);
        Maker maker = ctx.getBean(Maker.class);
        maker.printName();
    }
}

【讨论】:

  • 这里有什么解决方案可以让自动接线工作?
  • 这意味着,ServiceHelper 不会自动连接到 Maker,因为 Maker 没有添加到 Spring 应用程序上下文中。 Maker 是使用 new 关键字创建的。 Spring对此一无所知。
  • @Hima 我明白了。如果我想在 main 方法中调用 Maker,我想问如何解决这个问题?无法自动装配静态,无法使用“新”,这里的解决方案是什么?
  • 你可以查看我的回答,有几种方法可以@Autowirestatic beans @kang
【解决方案2】:

如果您使用new 关键字创建任何bean,该bean 将不会添加到Spring Application Context,这是@Autowire 静态bean 的一种方式

@SpringBootApplication
public class DemoApplication {

    @Autowired
    private static Maker maker; 

    @Autowired
    private Maker tMaker;

    @PostConstruct
    public void init() {
    DemoApplication.maker = tMaker;
}

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
        maker.printName();  
    }
}

或者您可以使用Constructor 执行AutowireMaker 的实例在创建DemoApplication 时作为参数注入构造函数

@Autowired
public DemoApplication(Maker maker) {
    DemoApplication.maker = maker;
    }

或者你可以在setter方法上使用@Autowired,当DemoApplication被创建时,setter方法被Maker的实例调用

@Autowired
public void setMaker(Maker maker) {
        DemoApplication.maker = maker
}

【讨论】:

  • 这当然有效。尽管根据上述评论,我认为静态自动布线是不可能的,但这似乎证明了它是可能的。
  • 还有更多方法@kang
  • 静态字段上的自动连线毫无意义。这里发生的是您正在自动装配第二个 Maker,即实例字段,并在 bean 之后将其设置为已初始化。
  • 更新了另一种方法,我只是提供静态 bean 的方法@DarrenForsythe
【解决方案3】:

当您使用 new Maker() 时,您没有使用 Spring 为您创建的 bean,因此您拥有的对象未初始化,因为未注入依赖项。

您需要获取 Spring 框架创建的 bean,就像我在下面直接做的那样,您无法自动装配静态字段:

@SpringBootApplication
public class DemoApplication {

    private static Maker maker;

    @Autowired
    public void setMaker(Maker maker) {
        DemoApplication.maker = maker;
    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
        maker.printName();
    }
}

【讨论】:

    猜你喜欢
    • 2020-11-06
    • 2021-01-17
    • 2019-08-17
    • 2014-08-17
    • 2021-07-02
    • 2020-08-31
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多