如何使用main(String [] args)方法中的自动装配(@Autowired)引用? [英] How to use autowired (@Autowired) references from main(String[] args) method?
问题描述
我正在尝试使用来自主类的自动引用,并且面临着:
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 PostConstruct
will be invoked one and once.
这篇关于如何使用main(String [] args)方法中的自动装配(@Autowired)引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!