Spring Boot: как получить доступ к хранилищу в Java-классе @Autowired не работает - PullRequest
0 голосов
/ 06 июля 2018

Spring Boot: как получить доступ к хранилищу в классе Java @Autowired не работает

Пожалуйста, объясните ваше решение с примером кода, поскольку я новичок в Spring Boot.

Репозиторий

import java.util.List;
import org.springframework.data.repository.CrudRepository;

public interface StoreRepository extends CrudRepository<Store, Integer> {

    List<Store> findAll();
}

Магазин Entity

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Store {

    @Id
    private Integer sid;
    private String sname;


    public Store() {

    }

    public Store(Integer sid, String sname) {
        super();
        this.sid = sid;
        this.sname = sname;

    }

///GETTER and Setters   here...

}

** Магазин Сервис **

import java.util.List;

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


@Service
public class StoreService {

    @Autowired
    private StoreRepository storeRepository;

    public StoreService() {

    }

    public List<Stores> getAllStores(){
        return (List<Stores>) storeRepository.findAll(); /* This works good. Through controller I can retrieve all data*/

    }

}

Простой класс Java

@Component
public class StoreWorker {

    @Autowired
    private StoreRepository storeRepository;

    public StoreWorker() {

        System.out.println(storeRepository.findAll()); /* Error */

    }

Ошибка:

Exception in thread "StoreWorker : restartedMain" java.lang.reflect.InvocationTargetException
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.store.workers.StoreWorker]: Constructor threw exception; nested exception is java.lang.NullPointerException
Caused by: java.lang.NullPointerException

Пожалуйста, объясните ваше решение с примером кода, поскольку я новичок в Spring Boot.

Ответы [ 3 ]

0 голосов
/ 06 июля 2018

Вы должны изменить свой код следующим образом:

Если вы хотите использовать ваш bean-компонент в конструкторе вашего класса, используйте инъекцию конструктора. Это также самый рекомендуемый способ инъекции.

@Component
public class StoreWorker {

    private final StoreRepository storeRepository;

    public StoreWorker(StoreRepository storeRepository) {
        this.storeRepository = storeRepository;
        System.out.println(storeRepository.findAll());
    }
}

Таким образом, когда создается экземпляр StoreWorker, автоматически вводится bean-компонент storeRepository. Поскольку это происходит, вы можете использовать storeRepository bean.

0 голосов
/ 06 июля 2018

Вы не должны помещать логику в конструктор. Методы конструктора предназначены только для инициализации вашего экземпляра. Сделайте вызов storeRepository в отдельном методе.

@Component
public class StoreWorker {
    @Autowired
    private StoreRepository storeRepository;

    public void findAll() {
        System.out.println(storeRepository.findAll()); 
    }
}

Когда Spring вызывает ваш конструктор, контекст инициализируется не полностью, и, поскольку вы не используете инъекцию конструктора, storeRepository еще не внедрен.

Внедрение в конструктор - это рекомендуемый способ внедрения командой Spring. А начиная с Spring 4.3 вам даже не нужно добавлять аннотацию @Autowired в конструкторы.

@Component
public class StoreWorker {

    private StoreRepository storeRepository;

    //@Autowired not needed since v4.3
    public StoreWorker(StoreRepository storeRepository) {
        this.storeRepository = storeRepository;
    }

    ...
}

Если вы хотите выполнить дальнейшую инициализацию вашего bean-компонента с использованием других внешних bean-компонентов, сделайте это отдельным методом, помеченным @PostConstruct.

@Component
public class StoreWorker {

    private StoreRepository storeRepository;
    private List<Store> stores;

    public StoreWorker(StoreRepository storeRepository) {
        this.storeRepository = storeRepository;
    }

    @PostConstruct
    public void initializeMyBean() {
        stores = storeRepository.findAll(); 
    }
}
0 голосов
/ 06 июля 2018

Вы должны использовать @Autowire на уровне конструктора, чтобы использовать переменную Autowire внутри конструктора.

@Component
public class StoreWorker {


@Autowired
public StoreWorker(StoreRepository storeRepository) {

    System.out.println(storeRepository.findAll()); 

}

(или) Использовать PostConstruct

Автопроводка происходит после постройки объекта. Поэтому они не будут установлены до завершения конструктора.

Если вам нужно запустить некоторый код инициализации, вы должны иметь возможность вставить код в конструкторе в метод и аннотировать этот метод с помощью @ PostConstruct.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...