如何使用main(String [] args)方法中的自动装配(@Autowired)引用? [英] How to use autowired (@Autowired) references from main(String[] args) method?

查看:281
本文介绍了如何使用main(String [] args)方法中的自动装配(@Autowired)引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用来自主类的自动引用,并且面临着:

I am trying to use an autowired reference from main class and am facing :

无法静态引用非静态字段 zipCodeLookupService.

Cannot make a static reference to the non-static field zipCodeLookupService.

这很明显.但是我想知道如何处理这种情况.涉及主类时自动接线的正确方法是什么?我的代码如下-

This is obvious. But I want to know how to handle this situation. What is the correct way of autowiring when main class is involved. My code will be as below -

接口类

package com.example.services;
public interface IZipCodeLookup {
    String retriveCityForZip(String zipCode);
}

服务等级

package com.example.services;

import org.springframework.stereotype.Service;

@Service
public class ZipCodeLookupService implements IZipCodeLookup {

    @Override
    public String retriveCityForZip(String zipCode) {

        //below is mock code. actual code does a db lookup using a DAO.
        if(zipCode=="94123") return "San Francisco";
        return "not found in DB";
    }
}

这是需要服务类的主要类

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.example.services.IZipCodeLookup;

@SpringBootApplication
public class AutowireWithMainClassApplication {

    @Autowired
    IZipCodeLookup zipCodeLookupService;

    public static void main(String[] args) {
        SpringApplication.run(AutowireWithMainClassApplication.class, args);
        String city;
        //this will not work, compilation error
        //Cannot make a static reference to the non-static field zipCodeLookupService
        city=zipCodeLookupService.retriveCityForZip(args[0]);

        System.out.println("city for zipcode " + args[0] + " is " +city);       
    }
}

有人可以建议-涉及主类时如何或正确的方式使用自动装配.

Could someone suggest - how or what is the correct way of using autowiring when main class is involved.

(因为将自动装配参考设为静态仍然无法工作)
AutowireWithMainClassApplication类中,更改为-

(As making the Autowired reference as static does not work anyway)
in AutowireWithMainClassApplication class, changing to -

@Autowired
static IZipCodeLookup zipCodeLookupService;

抛出

线程主"中的异常 java.lang.NullPointerException

Exception in thread "main" java.lang.NullPointerException

推荐答案

带有@SpringBootApplication批注的类不是经典的bean.
它从 static 创建Spring上下文.方法.
但是自动绑定的依赖项不能为静态.

A class annotated with a @SpringBootApplication annotation is not a classic bean.
It creates the Spring context from a static method.
But autowired dependencies cannot be static.

这就是为什么此声明:

city=zipCodeLookupService.retriveCityForZip(args[0]);

不会抛出Spring异常,而是抛出经典NullPointerException,因为您将zipCodeLookupService声明为static字段.

doesn't throw a Spring exception but a classic NullPointerException as you declare zipCodeLookupService as a static field.

在您的情况下,作为解决方法,您可以在主类中的使用javax.annotation.PostConstruct方法注释的实例方法中移动使用Spring Bean的处理,并存储传递给字段中的方法,以便以后可以使用它:

In your case, as workaround, you could move the processing that uses the Spring bean in a instance method annotated with javax.annotation.PostConstruct method inside your main class and store the arguments passed to the main() method in a field in order to be able to use it later :

private static String[] args;
@Autowired
IZipCodeLookup zipCodeLookupService;

public static void main(String[] args) {
    AutowireWithMainClassApplication.args = args;
    SpringApplication.run(AutowireWithMainClassApplication.class, args);
}

@PostConstruct
public void init() {
    String city=zipCodeLookupService.retriveCityForZip(args[0]);
    System.out.println("city for zipcode " + args[0] + " is " +city); 
}


要回答您的评论,您应注意有关@PostConstruct


To answer to your comment, you should note several things about @PostConstruct

1)它不是特定于Spring的注释.因此,官方文档可能会讨论比Spring更笼统的问题或特定但不同的事物,例如EJB(最初是为它们引入的).

1) It is not an annotation specific to Spring. So, the official documentation may discuss about things more general than Spring or specific but different things such as EJB (it was originally introduced for them).

2)Javadoc的第一句话概括了一般的预期行为.

2) The first sentence of the javadoc summarizes the general expected behavior.

PostConstruct批注用于需要使用的方法 在依赖项注入完成后执行以执行任何 初始化.

The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization.

但是这句话

在依赖项注入完成后执行"

"executed after dependency injection is done"

实际上是指:

在完成所有依赖项注入后执行"

"executed after all dependency injections are done"

我们通常讨论的是依赖注入,而不是每次依赖注入.
所以,是的,请坚持下去.

We talk about dependency injection in general, not about each dependency injection.
So, yes stick you to that.

将其应用于您的案例应该使事情更清楚.
AutowireWithMainClassApplication类被视为Spring Bean,因为@SpringBootApplication@Configuration注释,而@Configuration本身用@Component注释.
与任何Spring bean一样,它可以声明依赖项注入.
那是一个依赖注入:

Applying it to your case should make things clearer.
The AutowireWithMainClassApplication class is considered as a Spring bean as @SpringBootApplication is annotated with @Configuration that is itself annotated with @Component.
And as any Spring bean, it may declare dependency injection.
That is a dependency injection :

@Autowired
IZipCodeLookup zipCodeLookupService;

但是您当然可以声明您想要的尽可能多的依赖项注入:

But you could of course declare as many dependency injections that you want to :

@Autowired
IZipCodeLookup zipCodeLookupService;

@Autowired
OtherClass otherClass;

...

因此,只有有效注入所有依赖项时,PostConstruct才会被调用一次.

So only as all dependencies are effectively injected, the PostConstructwill be invoked one and once.

这篇关于如何使用main(String [] args)方法中的自动装配(@Autowired)引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆