2016-04-12 1 views
0

Я пишу небольшое приложение Spring, состоящее из модели, представленной фасадным объектом с именем service и представлением на основе JSP. Между ними у меня есть обычные контроллеры Spring и конвертер, который преобразует идентификатор строки в объект из модели.Не удается получить доступ к объекту с автоподстановкой в ​​преобразователе Spring

Этот преобразователь использует служебный объект, который является @Autowired, чтобы найти нужный объект модели от service. Проблема в том, что всякий раз, когда конвертер обращается к методу в service, ничего не происходит. Нет ошибок или исключений, он просто продолжается и возвращает null.

Я уже проверил, правильно ли инициализирован service, и это не похоже на проблему. Во время отладки я заметил, что программа проходит через ThreadPoolExecutor и останавливается там, когда я пытаюсь выполнить метод на service. Это заставляет меня предположить, что проблема связана с доступом к service, пока он заблокирован.

Я уже пытался поместить необходимый код в синхронизированный блок, но это не помогает. Может ли кто-нибудь сказать мне, почему я не могу получить доступ к каким-либо методам из объекта @Autowired в конвертере Spring?

Вот класс конвертера для чего это стоит:

public class IdToPublisherConverter implements Converter<String, Publisher>{ 

    @Autowired 
    private MainService service; 

    @Override 
    public Publisher convert(String id) { 
     return service.getPublisher(Long.getLong(id)); 
    } 
} 

EDIT:

MainService является объектом фасада, который предоставляет интерфейс для получения, добавлять, обновлять и удалять мои данные модели (Game объектов и Publisher объектов)

service.getPublisher(id) получает объект Publisher от service, основанный на идентификаторе типа длинный конвертер, полученный со страницы JSP. Этот метод переходит к следующему методу в MainService:

@Override 
public Publisher getPublisher(long id) { 
    Publisher publisher = repository.readPublisher(id); 
    return publisher; 
} 

Который идет в:

private final Map<Long, Publisher> publishers; 

... 

@Override 
public Publisher readPublisher(long id) { 
    return publishers.get(id); 
} 
+1

Что такое 'MainService'? Что делает 'getPublisher'? Укажите [MCVE]. – Savior

+1

Вы уже заявляете, что инициализируется «service» (и, таким образом, выполняется аутсорсинг) и определяется, что объект, на который ссылается «service», заблокирован. Поэтому нам нужно посмотреть, что делает 'service.getPublisher (...)' (код, а не описание), чтобы рассказать вам, почему он заблокирован и т. Д. – Thomas

+0

Вы уверены, что карта 'издателей в вашем репозитории не пуст? – home

ответ

-1

Проверьте, если ваша служба имеет @Service аннотацию, например

@Service("mainService") 
public class MainService... 

и внутри него, если у вас есть транзакционные методы, не забудьте @Transactional

С несколькими кодами показал, что это сложно, но я думаю, что это помогает вам, если это так.

+0

Я не уверен, что делают аннотации '@ Service' и' @ Transactional', но я не хочу использовать какие-либо элементы Spring для моего бэкэнд. Поддержание свободной связи между моим взглядом и моей моделью является для меня первоочередной задачей. – Exevan

+1

@Exevan Я думаю, что эти аннотации прекрасны, когда мне нужна гибкость между представлением и моделью, важно иметь много уровней, класс с аннотацией сервиса практически не зависит от вашего вида и модели ... с представлением с использованием бэк-компонента нужно только вызывать службу, как вам угодно, например, если вы хотите дезагрегировать еще несколько, вы также можете включить класс делегата в качестве компонента (аннотацию) и вызвать свои службы через него ... так что ваша модель и ваше представление будут более гибкими, если вам понадобятся изменения –

0

Итак, после часа возиться, я, наконец, нашел и решил свою проблему. Проблема не связана с многопотоковой обработкой, а скорее с преобразованием из String в long. Вместо того чтобы использовать Long.getLong(id), я должен использовать что-то вроде этого:

@Override 
public Publisher convert(String idString) { 
    return service.getPublisher(Long.parseLong(idString)); 
} 
0

попытки добавить @Component аннотации к конвертору. Убедитесь, что ваш конвертер зарегистрирован в SpringConfiguration

@Configuration 
@EnableWebMvc 
@ComponentScan 
public class ServerConfig extends WebMvcAutoConfigurationAdapter { 
    @Override 
    public void addFormatters(FormatterRegistry formatterRegistry) { 
     converterAutoscanner(formatterRegistry); 
     super.addFormatters(formatterRegistry); 
    } 

    @SuppressWarnings("rawtypes") 
    private void converterAutoscanner(FormatterRegistry formatterRegistry) { 
     Reflections reflections = new Reflections("com.somepackege"); 
     Set<Class<? extends Converter>> allClasses = reflections.getSubTypesOf(Converter.class); 
     allClasses.forEach(s -> { 
      try { 
       formatterRegistry.addConverter(s.newInstance()); 
      } catch (Exception e) { 
       LOGGER.error(e); 
      } 
     }); 
    } 
} 


@Component 
public class CommentConverter implements Converter<String, Comment>{ 
    //converter code 
} 
0

Вам нужно определить IdToPublisherConverter как фасоль.как этого

@Service 
public class IdToPublisherConverter... 

Только бобы инициализированными можно использовать @Autowired аннотацию, в противном случае вы получите нулевой. Если IdToPublisherConverter не является компонентом, пользовательский класс PathpathXmlApplicationcontext получает весенние бобы.