我正在尝试使用主类的自动引用,并且面临:
无法静态引用非静态字段zipCodeLookupService。
这是显而易见的。但是我想知道如何处理这种情况。涉及主类时自动接线的正确方法是什么?我的代码如下-
接口类
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);
}
}
有人可以建议-涉及主类时如何或正确的方式使用自动装配。
(由于将Autowired引用设为静态仍然无法工作)
在AutowireWithMainClassApplication
课堂上,更改为-
@Autowired
static IZipCodeLookup zipCodeLookupService;
抛出
线程“主”中的异常java.lang.NullPointerException
用@SpringBootApplication
注解注解的类不是经典bean。
它从 静态 方法创建Spring上下文。
但是自动装配的依赖关系不能是 静态的 。
这就是为什么此声明:
city=zipCodeLookupService.retriveCityForZip(args[0]);
不会引发Spring异常,而是引发NullPointerException
您声明zipCodeLookupService
为static
字段的经典异常。
在您的情况下,作为一种解决方法,您可以将使用Spring bean的处理移到 实例 方法中,该 实例
方法javax.annotation.PostConstruct
在您的主类内以方法注释,并将传递给该main()
方法的参数存储在字段中,以便以后可以使用它:
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
1)它不是特定于Spring的注释。因此,官方文档可能会讨论比Spring更通用的事物或特定但不同的事物,例如EJB(最初是为它们引入的)。
2)Javadoc的第一句话总结了一般的预期行为。
PostConstruct批注用于需要依赖注入完成以执行任何初始化之后需要执行的方法上。
但是这句话
“完成依赖项注入后执行”
的确意味着:
“在完成所有依赖项注入后执行”
我们通常谈论依赖注入,而不是每次依赖注入。
所以,是的,请坚持这一点。
将其应用于您的案例应该使事情更清楚。
将AutowireWithMainClassApplication
作为类被认为是一个Spring bean
@SpringBootApplication
标注有@Configuration
其本身标注了@Component
。
和任何Spring bean一样,它可以声明依赖注入。
那是一个依赖注入:
@Autowired
IZipCodeLookup zipCodeLookupService;
但是,您当然可以声明您想要的尽可能多的依赖项注入:
@Autowired
IZipCodeLookup zipCodeLookupService;
@Autowired
OtherClass otherClass;
...
因此,只有在 所有 依赖项都被有效注入后,PostConstruct
才会被调用一次。
问题内容: 之间有什么区别: 和 我不相信,但是我想知道。 问题答案: 从语义上讲,它们是相同的。但是,我建议在声明数组时使用后一种语法()。以前的语法主要用于与C语法兼容。 因为总体上来说,它是Java中对象的类型,所以它更加一致,而且很清楚不要将其拆分。
问题内容: 在下面的摘录中,您如何向 初学者 很好地解释的含义和用法? 问题答案: 我将向初学者介绍有关Main函数的Wiki文章,然后对此进行补充。 Java只开始运行具有特定签名的程序,并且人们可以将签名视为自己的名字-这就是Java如何分辨别人的签名和true 的区别。 是s 的集合,以空格分隔,可以在终端上将其键入程序中。初学者不会多次使用此变量,但总是以防万一。
在上面的代码中,为什么在< code>main()中强制提到< code>String args[]以及为什么我们得到< code > "[ljava . lang . String;@174e5edb"作为输出?
问题内容: 首先-是的,我知道这很疯狂/奇怪。但是我需要它:)。 我想找到 在Android Studio中 运行单个Java文件的最简单方法 (并且更喜欢非终端答案:)-如果可能的话)。我的意思是我的Android项目中有一个随机的.java文件,我将在其中编写main(..)方法。还有一件事: 我不想创建任何新模块 (我已经看到了有关添加Java库模块的答案)。我只想单击某些东西并运行我的(单
在执行下面的程序时,我得到错误消息为“错误:在类parent_package.parent中找不到Main方法,请将Main方法定义为:public static void Main(String[]args)”..................有谁知道如何解决这个问题吗?
我有一个bean,我必须自己创建它(使用),它有和注释。 如何让Spring处理我的bean中的这些注释? 相关问题: 在Spring,我可以从自动编织的豆子里自动编织新的豆子吗?