Лучшая практика для реализации бобов весной - PullRequest
0 голосов
/ 20 февраля 2020

У меня есть класс mapper, который выполняет сложное сопоставление одного pojo другому. Я сделал класс картографа бобом и связал его с классом обслуживания. Я мог бы также сделать класс mapper классом stati c, но я предпочел бин, потому что я чувствовал его лучше с точки зрения тестируемости, я могу независимо тестировать сервис и мапперы, издеваясь над мапперами. Действительно, также возможно издеваться над классами stati c, но мне придется использовать powermock или что-то подобное. Другая причина выбора bean-компонента заключается в том, что для определенных преобразователей мне приходилось использовать интерфейсы, чтобы я мог выбирать реализацию преобразователя на основе определенных условий данных.

Эта реализация в виде bean-компонента вызвала спор в моей команде с предложениями реализовать его как класс с помощью метода карты stati c или каждый раз создавать новые объекты mapper. И мы пытаемся выяснить, что является лучшим решением. Соблюдаются ли какие-либо отраслевые стандарты? Есть ли компромиссы с подходом бобов? Может ли это повлиять на производительность моего приложения? представьте, что у меня есть сто таких картографов. Ниже приведен простой Skelton о том, как выглядит мой сервис и картографы.

@Service 
class CustomerService { @Autowired CustomerMapper customerMapper ...}

@Component 
class CustomerMapper { @Autowired CustomerContactMapper ..
}

interface CustomerContactMapper {}

@Component
class InternalCustomerContactMapper implements CustomerContactMapper {}

@Component
class ExternalCuatomerContactMapper implements CustomerContactMapper {}

1 Ответ

3 голосов
/ 20 февраля 2020

Ну, может быть много мнений, если вы хотите следовать соглашениям, предложенным весной, то вы все сделали правильно.

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

class CustomerService {
    private final CustomerMapper customerMapper;

    public CustomerService(CustomerMapper customerMapper) {
        this.customerMapper = customerMapper;
    }
}

Сторона Примечание : если вам не нравится «шаблон» конструктора, вы можете в любом случае использовать Lombok, который предоставляет «AllArgsConstructor».

Теперь некоторые моменты, касающиеся производительности: Spring инициализирует bean-компоненты во время запуска применение. Если это простые для создания классы (классы, которые не загружают много материала при создании, не go в БД и т. Д., Просто простые java объекты), то для инициализации требуются частицы секунды торговый центр.

Позже у вас есть обычный вызов функции (хорошо, если вы работаете с интерфейсом, тогда это «виртуальный» вызов), но в целом это не влияет на производительность, другими словами, если приложение работает медленно, причина, вероятно, кроется где-то еще.

По поводу альтернативы:

Я не совсем понял, что означает «реализовать как класс c», однако, если вы хотите каждый раз создавать новый маппер, это будет означать, что он не безопасен для потоков. В текущей реализации служба является одноэлементной, поэтому ее экземпляров не будет много, это будет только один экземпляр на контекст приложения. Однако он может вызываться многими потоками одновременно.

Так что, если вам нужно создать много экземпляров -> преобразователь не может использоваться из многих потоков. Это решение не имеет никакого отношения к Spring, вашему коду и вашему решению сделать его не поточно-безопасным (я не говорю, хорошо это или плохо, просто констатирую факт).

Теперь, если это если это так, то ваше решение технически неверно. Spring поддерживает этот вид использования с помощью класса Provider + есть и другие способы внедрения прототипа в синглтон:

class CustomerService {
    private final Provider<CustomerMapper> customerMapper;

Вы можете прочитать Здесь об этом методе

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