Может @Autowire @Service bean-компоненты, но не члены класса, для которого создается ключевое слово «new» - даже если настроено сканирование контекста - PullRequest
1 голос
/ 22 августа 2011

У меня есть приложение, которое хорошо работает с @Autowired @Service бобами.

Теперь я добавляю класс Validator, который создается в Контроллере:

BlueValidator validator = new BlueValidator(colors);
validator.validate(colorBlend, bindResult);

В классе BlueValidator я пытаюсь @Autowire blendService, который работает как поле @Autowired в другом месте приложения:

public class BlueValidator implements Validator {
@Autowired
private BlendService blendService;
private Colors colors;

Но по какой-то причине после создания экземпляра BlueValidator я продолжаю получать NullPointerException s для blendService.

Конечно, я добавил необходимое сканирование контекста:

<context:component-scan 
base-package="com.myapp.controllers, com.myapp.services, com.myapp.validators" />

Я также попытался добавить аннотацию @Autowired в конструктор, но это не помогло:

@Autowired
public BlueValidator(Colors colors) {
    this.colors = colors;
}

Должен ли я просто передать blendService на BlueValidator и забыть об автопроводке или здесь что-то не хватает очевидного?

Ответы [ 4 ]

1 голос
/ 22 августа 2011

Когда вы создаете экземпляры объектов, Spring ничего не может для них сделать, поэтому не вводятся зависимости ( article ).

В вашем случае у вас есть несколько вариантов:

  • передать зависимости в валидатор из контроллера (где вы можете ввести их)
  • делает валидатор пружинным компонентом и внедряет его, а не создает его
  • use @Configurable, который через AspectJ включает впрыск пружины даже в объектах, созданных с помощью new
1 голос
/ 22 августа 2011

Если вы просто создаете экземпляр объекта с помощью new, Spring не задействуется, поэтому автоматическое подключение не срабатывает. Сканирование компонентов просматривает классы и создает объекты из них - оно не смотрит на объекты, которые вы создаете сами.

Этот можно заставить работать, используя Поддержка AspectJ в Spring , но это требует некоторых усилий.

В противном случае вам нужно разрешить Spring создать экземплярваши объекты, если вы хотите, чтобы автоматическая проводка работала.

Должен ли я просто передать blendService BlueValidator и забыть об автоматической проводке

В вашей ситуации я бы сказал, что да, это решение с наименьшими усилиями.

0 голосов
/ 23 сентября 2011

Не создавайте валидатор вручную - разрешите Spring сделать эту работу за вас:

@Controller
class Controller {

    @Autowired
    BlueValidator validator;

    void doSomething() {
        ...
        validator.validate(colorBlend, bindResult);
        ...
    }

}

Также обратите внимание, что добавления пакета com.myapp.validators к context:scan-packages недостаточно, вы также должны аннотироватькласс валидатора с @Component аннотацией:

@Component
public class BlueValidator implements Validator {
@Autowired
private BlendService blendService;

(Кстати, это решение работает в моем проекте.)

0 голосов
/ 22 августа 2011

@Autowired используется Spring'ом ApplicationContext для заполнения этих полей при создании.Так как ApplicationContext не тот, кто создает эти bean-компоненты (вы из-за ключевого слова 'new'), они не подключаются автоматически.Вам нужно передать это в себя, если вы создаете это.

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