Поделитесь несколькими практическими советами по SpringBoot

задняя часть база данных Spring контейнер
Поделитесь несколькими практическими советами по SpringBoot

предисловие

Недавно были опубликованы некоторые элементы исходного кода и дизайна фреймворка. Я обнаружил, что энтузиазм у всех не особенно высок, поскольку большинство из них считают, что они должны быть серьезными программистами; на этот раз я поделюсь небольшим обоснованием:SpringBootНекоторые хитрости в использовании.

Это не имеет большого значения, но это довольно полезно.

Блокировать внешние зависимости

первый屏蔽外部依赖,Что это обозначает?

Например, есть ли у вас такие проблемы в ежедневном развитии:

проект основан наSpringCloudилиdubboДля такой распределенной службы вам нужно полагаться на множество базовых служб.

Например, генерация номера заказа, получение информации о пользователе и т. д.

Из-за разделения сервисов эти функции предоставляются в виде интерфейсов в других приложениях, к счастью, я все еще могу использовать одиночный тест.MockЗаблокируйте это.

Но что, если вы хотите одновременно запустить приложение и связанный с ним код?

Обычно существует несколько подходов:

  • Запустите все службы локально.
  • Измените реестр на среду разработки и полагайтесь на услуги среды разработки.
  • Отправьте код непосредственно в среду разработки для самотестирования.

Похоже, все три в порядке, и я делал то же самое раньше. Но есть еще несколько небольших проблем:

  • Сервисов в локальном автозапуске может быть очень много.Сможет ли комп задержать их все-это еще вопрос.Если проблема со службой, то она дальше не пойдет.
  • Предпосылка использования среды разработки заключается в том, что сеть открыта.Другая проблема заключается в том, что код среды разработки очень нестабилен и может повлиять на ваши тесты.
  • Отправка в среду разработки должна быть более надежным решением, но если вы хотите отладить, есть только метод журнала, а не локальный.debugэффективности.

Итак, как решить проблему? Вы можете выполнять отладку локально, не запуская другие службы.

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

Общий процесс делится на следующие этапы:

  • SpringBootпосле запускаSpringНайдите тот, который вам нужно заблокироватьAPIизbean(Обычно этот интерфейс передаетсяSpringудалось).
  • вручную изbeanудалить контейнерbean.
  • воссоздатьAPIобъект, только черезMockот.
  • Зарегистрируйтесь вручнуюbeanв контейнере.

В качестве примера возьмем следующий код:

    @Override
    public BaseResponse<OrderNoResVO> getUserByHystrix(@RequestBody UserReqVO userReqVO) {

        OrderNoReqVO vo = new OrderNoReqVO();
        vo.setAppId(123L);
        vo.setReqNo(userReqVO.getReqNo());
        BaseResponse<OrderNoResVO> orderNo = orderServiceClient.getOrderNo(vo);
        return orderNo;
    }

Это приложение SpringCloud.

это зависит отorderServiceClientПолучить один номер заказа.

один из нихorderServiceClientЭто внешний API, и им также управляет Spring.

Замените оригинальный бин

Следующим шагом является замена исходного компонента.

@Component
public class OrderMockServiceConfig implements CommandLineRunner {

    private final static Logger logger = LoggerFactory.getLogger(OrderMockServiceConfig.class);

    @Autowired
    private ApplicationContext applicationContext;

    @Value("${excute.env}")
    private String env;

    @Override
    public void run(String... strings) throws Exception {

        // 非本地环境不做处理
        if ("dev".equals(env) || "test".equals(env) || "pro".equals(env)) {
            return;
        }

        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();

        OrderServiceClient orderServiceClient = defaultListableBeanFactory.getBean(OrderServiceClient.class);
        logger.info("======orderServiceClient {}=====", orderServiceClient.getClass());

        defaultListableBeanFactory.removeBeanDefinition(OrderServiceClient.class.getCanonicalName());

        OrderServiceClient mockOrderApi = PowerMockito.mock(OrderServiceClient.class,
                invocationOnMock -> BaseResponse.createSuccess(DateUtil.getLongTime() + "", "mock orderNo success"));

        defaultListableBeanFactory.registerSingleton(OrderServiceClient.class.getCanonicalName(), mockOrderApi);

        logger.info("======mockOrderApi {}=====", mockOrderApi.getClass());
    }
}

который понялCommandLineRunnerинтерфейс, который может бытьSpringВызывается после инициализации контейнераrun()метод.

Код очень простой.Короче говоря, сначала определите, что такое окружение.Ведь кроме локального окружения, остальным нужно собственно вызывать удаленный сервис.

затем получитьbeanЗатем удалите его вручную.

Важный шаг:

OrderServiceClient mockOrderApi = PowerMockito.mock(OrderServiceClient.class,
                invocationOnMock -> BaseResponse.createSuccess(DateUtil.getLongTime() + "", "mock orderNo success"));

defaultListableBeanFactory.registerSingleton(OrderServiceClient.class.getCanonicalName(), mockOrderApi);

создал новыйOrderServiceClientобъекта и вручную зарегистрирован вSpringв контейнере.

Первый фрагмент кода используетPowerMockito.mockAPI, он может создать прокси-объект, который разрешает все вызовыOrderServiceClientметоды будут выполнять возврат по умолчанию.

BaseResponse.createSuccess(DateUtil.getLongTime() + "", "mock orderNo success"))

Протестируй, когда не заменим, вызываем интерфейс только сейчас и локально не запускаетсяOrderService:

Поскольку откат не настроен, будет сообщено об ошибке, указывающей, что служба не может быть найдена.

При замене фасоли:

Запрошен снова без ошибок и получил возврат по умолчанию.

Также нашел в журналеOrderServiceClientнаконец-тоMockПрокси и не будет вызывать реальный метод.

Настроить шифрование

Следующий — настроить шифрование, которое следует считать основной функцией.

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

Поэтому на этот раз для реализации шифрования и дешифрования используется компонент с открытым исходным кодом.SpringBootОчень дружелюбный и может быть сделан с помощью всего нескольких фрагментов кода.

  • Сначала зашифруйте конфигурацию, которая должна быть зашифрована в зашифрованный текст в соответствии с паролем шифрования.
  • Замените исходную конфигурацию, сохраненную в виде открытого текста.
  • Расшифровать при повторном использовании.

Чтобы использовать этот пакет, вам нужно только ввести зависимость:

<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>1.14</version>
</dependency>

При этом напишите один тест для генерации шифротекста по паролю, а пароль так же можно сохранить в конфигурационном файле:

jasypt.encryptor.password=123456

Затем зашифрованный текст генерируется в одном тесте.

    @Autowired
    private StringEncryptor encryptor;

    @Test
    public void getPass() {
        String name = encryptor.encrypt("userName");
        String password = encryptor.encrypt("password");
        System.out.println(name + "----------------");
        System.out.println(password + "----------------");

    }

Тогда просто используйте зашифрованный текст.

Поскольку здесь я шифрую имя пользователя и пароль базы данных, происходит процесс расшифровки.

использоватьSpring BeanРасширенный интерфейс может быть реализован:

@Component
public class DataSourceProcess implements BeanPostProcessor {


    @Autowired
    private StringEncryptor encryptor;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        if (bean instanceof DataSourceProperties){
            DataSourceProperties dataSourceProperties = (DataSourceProperties) bean;
            dataSourceProperties.setUsername(encryptor.decrypt(dataSourceProperties.getUsername())) ;
            dataSourceProperties.setPassword(encryptor.decrypt(dataSourceProperties.getPassword()));
            return dataSourceProperties ;
        }

        return bean;
    }
}

Таким образом, он может быть восстановлен в виде открытого текста, когда он действительно используется.

Вы также можете настроить пароль прямо сейчас в команде запуска:

java -Djasypt.encryptor.password=password -jar target/jasypt-spring-boot-demo-0.0.1-SNAPSHOT.jar

Суммировать

Это конец двух маленьких трюков, которые есть у каждого.SpringBootДля получения дополнительных навыков использования, пожалуйста, оставьте сообщение для обсуждения.

Некоторый пример кода для вышеизложенного можно найти здесь:

GitHub.com/crossover J я…

Добро пожаловать, чтобы обратить внимание на публичный аккаунт, чтобы общаться вместе: