【问题标题】:Simple Spring Java @Configuration to @Autowire without @Bean没有 @Bean 的简单 Spring Java @Configuration 到 @Autowire
【发布时间】:2019-05-30 08:48:51
【问题描述】:

我想在 java rest 项目中使用 spring @Autowired。在过去的几天里,我正在尝试使用 java 配置设置一个简单的 spring java 项目,而没有明确的 bean 配置来检查该功能。但我无法让它工作。我可能遗漏了一些基本的东西。

到目前为止,我在网络和本网站上找到的方法都没有解决我的问题。我也找不到我想要达到的目标的样本。这主要是由于网络上存在大量不同的 spring 版本和方法。

这是一个尽可能简单的 Java Spring 休息示例。我添加了一些关于我如何解释 spring 注释的 cmets,因为我也可能在这里犯错:

应用基类

package restoverflow;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("/")
public class App extends Application {

}

配置类

package restoverflow;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration  //this is a configuration class and also found by spring scan
@ComponentScan  //this package and its subpackages are being checked for components and its subtypes
public class AppConfig {

}

一些波乔

package restoverflow;

public class Pojo {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

一项服务

package restoverflow;

import org.springframework.stereotype.Service;

@Service //this is a subtype of component and found by the componentscan
public class PojoService {
    public Pojo getPojo(){
        Pojo pojo = new Pojo();
        pojo.setName("pojoName");
        return pojo;
    }
}

最后是应该完成服务自动装配的资源

package restoverflow;

import javax.ws.rs.GET;

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;

import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/resource")
@Controller //this is a subtype of component and found by the componentscan
public class Resource {

    @Autowired //this tells to automatically instantiate PojoService with a default contructor instance of PojoService
    private PojoService pojoService;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Pojo getPojo() {
        return pojoService.getPojo();
    }
}

波姆:

...
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.7.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.1.7.RELEASE</version>
</dependency>
...

我希望 pojoService 被实例化。但我得到一个 NullPointerException。

【问题讨论】:

    标签: java spring configuration autowired


    【解决方案1】:

    您似乎正在使用字段级注入。

    请通过以下链接了解所有类型的注射: https://www.vojtechruzicka.com/field-dependency-injection-considered-harmful/

    看不出 pojoService 变为空的任何明确原因。 请检查 pojoService bean 是否被正确初始化。这可能是由于 pojoService bean 尚未初始化,而您的控制器中为 null。

    【讨论】:

    • 感谢您提供有关注入类型的信息!至于 pojoService:当我添加 public Resource() { System.out.println("pojoService: "+pojoService); } 时它为空。 PojoService 的构造函数永远不会被调用。
    • 我已经提到 PojoService bean 可能没有被初始化,这就是为什么 PojoService 的构造函数没有被调用。请检查组件扫描是否负责执行此操作。
    • 添加 ```public App () { applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);`` 后,PojoService 构造函数最终被调用。但是,正如上面评论中提到的,当我调用其余资源时,即资源 getPojo 方法,服务虽然在资源构造函数中成功自动装配,但仍然为空。编辑:启动时的 Resource 实例确实自动装配成功,但是当调用其余资源时,那是另一个实例并且没有成功自动装配
    • 试试用setter注入代替字段注入,看看是否能解决问题。
    • 这并没有解决它。我从 spring+jersey 到 spring boot 进行了技术更改,现在可以使用。不过,我无法想出解决原始问题的方法。
    【解决方案2】:

    nullpointer 而不是 NoSuchBeanDefinitionException 更多地表明 Spring 上下文根本没有加载,而不是加载不正确。

    如果您使用的是 Spring boot,请修改您的主类以初始化 Spring:

    @SpringBootApplication
    @ApplicationPath("/")
    public class App extends Application {
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    }
    

    或者(因为 pom.xml sn-p 没有提到 Spring boot),通过初始化 ClassPathXmlApplicationContext 并在 applicationContext.xml 中添加 &lt;context:component-scan base-package="restoverflow" /&gt; 来手动初始化 Spring。

    【讨论】:

    • 这不是 Spring Boot 应用程序,对。它在我的 src 文件夹中尝试了@ApplicationPath("/") @Configuration @ComponentScan public class App extends Application { private static ApplicationContext applicationContext; public static void main(String[] args) { applicationContext = new ClassPathXmlApplicationContext();along 和 applicationContext.xml ``` ``` 但这还不够。
    • 在构造函数中初始化它(它是一个 web 应用程序)时,它实际上可以设置上下文并在我调用其余资源时实例化 beans public App () { applicationContext = new AnnotationConfigApplicationContext(AppConfig.class); ,即资源 getPojo 方法、服务,而在资源构造函数中成功自动装配,仍然为空。
    猜你喜欢
    • 2018-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-27
    • 2015-09-02
    • 1970-01-01
    相关资源
    最近更新 更多