为什么@Autowired不能一直工作?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么@Autowired不能一直工作?相关的知识,希望对你有一定的参考价值。

我试图用Spring Boot设置mongodb,我不是在使用context.xml,而是尝试使用配置类和注释进行配置。

package com.configuration;

import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@Configuration
@EnableMongoRepositories(basePackages = "com.mongo")
public class MongoConfig extends AbstractMongoConfiguration {

    @Override
    protected String getDatabaseName() {
        return "mongodbname";
    }

    @Override
    public Mongo mongo() throws Exception {
        return new MongoClient("127.0.0.1", 27017);
    }
    @Override
    protected String getMappingBasePackage() {
        return "com.mongo";
    }
}

我的存储库看起来像这样:

package com.mongo.repositories;

import com.mongo.documents.Sequence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository("sequenceRepository")
public class SequenceRepository{
    @Autowired
    private MongoTemplate mongoTemplate;

    public Sequence findOne(Query query){
        return this.mongoTemplate.findOne(query,Sequence.class);
    }

    public List<Sequence> find(Query query){
        return this.mongoTemplate.find(query,Sequence.class);
    }

    public void save(Sequence object){
        this.mongoTemplate.save(object);
    }

    public void delete(Sequence object){
        this.mongoTemplate.remove(object);
    }
}

如果我在其余的控制器中使用这样的它正常工作:

package com.controllers;

import com.mongo.documents.Sequence;
import com.mongo.repositories.SequenceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {
    @Autowired
    private SequenceRepository sequenceRepository;

    @RequestMapping("/")
    public String index(){
        Sequence sequence = new Sequence();
        sequence.setClassName("class.Test");
        sequence.setActual(1);
        sequenceRepository.save(sequence);
        return "index";
    }
}

但是,如果我想在Sequence文档中使用SequenceRepository,如下所示:

package com.mongo.documents;

import com.mongo.repositories.SequenceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document
public class Sequence {

    @Autowired
    private SequenceRepository sequenceRepository;

    @Id
    private String id;

    private String className;

    private int actual;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public int getActual() {
        return actual;
    }

    public void setActual(int actual) {
        this.actual = actual;
    }

    public void save(){
        this.sequenceRepository.save(this);
    }

    public void delete(){
        this.sequenceRepository.delete(this);
    }
}

之后,我将控制器中的代码更改为:

package com.controllers;

import com.mongo.documents.Sequence;
import com.mongo.repositories.SequenceRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexController {
    @Autowired
    private SequenceRepository sequenceRepository;

    @RequestMapping("/")
    public String index(){
        Sequence sequence = new Sequence();
        sequence.setClassName("class.Test");
        sequence.setActual(1);
        sequence.save();
        return "index";
    }
}

我在save()方法中此时得到了一个nullPointerException。

答案

没有必要在您的域对象Sequence中注入您的存储库,因为在域对象和存储库类之间存在依赖关系是非常糟糕的设计。

要遵循一些好的做法,你的Service类或者如果你不需要服务层,你的Controller类应该注入你的存储库bean。

在您的上一个代码段中,您已经在执行此操作,但应在您的存储库.save()上调用SequenceRepository方法,而不是在域对象Sequence上调用。

一个例子如下:

@RestController
public class IndexController {

    @Autowired
    private SequenceRepository sequenceRepository;

    @RequestMapping("/")
    public String index(){

        Sequence sequence = new Sequence();
        sequence.setClassName("class.Test");
        sequence.setActual(1);


        // now let's save it
        sequenceRepository.save(sequence);
        return "index";
    }
}
另一答案

您只能将Spring管理的组件自动装配到其他Spring管理的组件中。您的序列对象不是组件(不使用@ Component,@ Service,@ Repository或@Controller等注释)

我建议你按照rieckpil的建议。

以上是关于为什么@Autowired不能一直工作?的主要内容,如果未能解决你的问题,请参考以下文章

初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段

Xcode 8 Autocomplete Broken - 仅显示有限的用户代码片段 - 知道为啥吗?

为啥@Autowired 在@Configuration 内部没有@Component 工作

试图替换片段,但它一直显示相同的片段

@Autowired注解(转)

spring的自动装配,骚话@Autowired的底层工作原理