Maison >Java >javaDidacticiel >Partage de compétences pratiques sur SpringBoot

Partage de compétences pratiques sur SpringBoot

不言
不言avant
2018-10-15 13:35:272275parcourir

Le contenu de cet article est de partager des conseils pratiques sur SpringBoot. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. J'espère qu'il vous sera utile.

Avant-propos

Quelques éléments de conception de code source et de framework qui ont été partagés récemment. J'ai trouvé que tout le monde n'était pas très enthousiaste. En y réfléchissant, la plupart d'entre eux devraient sérieusement écrire du code. Cette fois, je vais partager quelque chose de terre-à-terre : quelques conseils sur l'utilisation de SpringBoot.

Ce n’est pas quelque chose de sophistiqué, mais c’est très utile.

Protéger les dépendances externes

La première consiste à bloquer les dépendances externes. Qu'est-ce que cela signifie ?

Par exemple, rencontrez-vous de tels problèmes lors du développement quotidien :

Le projet est basé sur des services distribués tels que Spring Cloud ou dubbo, et vous devez vous appuyer sur de nombreux services de base.

Par exemple, générer un numéro de commande, obtenir des informations sur l'utilisateur, etc.

En raison du fractionnement des services, ces fonctions sont fournies sous forme d'interfaces dans d'autres applications. Heureusement, je peux également utiliser Mock pour les bloquer dans le test unique.

Mais que se passe-t-il si vous souhaitez démarrer l'application et exécuter votre propre code associé en même temps ?

Il existe généralement plusieurs méthodes :

  • Démarrez tous les services localement.

  • Changez le centre d'enregistrement en environnement de développement et comptez sur les services de l'environnement de développement.

  • Poussez le code directement dans l'environnement de développement pour un auto-test.

Il semble que les trois soient acceptables, et je l'ai déjà fait. Mais il reste encore quelques petits problèmes :

  • Les startups locales peuvent avoir de nombreux services, et il n'est pas clair si l'ordinateur peut tous les prendre en charge en cas de problème avec le service. , ça ne continuera pas.

  • La condition préalable pour s'appuyer sur l'environnement de développement est que le réseau soit ouvert. Un autre problème est que le code de l'environnement de développement est très instable et peut affecter vos tests.

  • Le push vers l'environnement de développement devrait être une solution plus fiable, mais si vous souhaitez déboguer, il n'existe que la méthode log, qui n'est pas aussi efficace que le débogage local.

Alors comment résoudre le problème ? Vous pouvez déboguer localement sans démarrer d'autres services.

En fait, vous pouvez également utiliser la méthode de test unique et simplement supprimer les autres dépendances externes Mock.

Le processus approximatif est divisé en les étapes suivantes :

  • Après le démarrage de SpringBoot, recherchez le bean de l'API que vous devez protéger au printemps (généralement, cette interface est It est géré par Spring).

  • Retirez manuellement le grain du récipient à grains.

  • Créez un objet de cette API, mais il vient tout juste de sortir de Mock.

  • Ensuite, enregistrez-le manuellement dans le conteneur à grains.

Prenons le code suivant comme exemple :

    @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;
    }</ordernoresvo></ordernoresvo>
Il s'agit d'une application SpringCloud.

Il s'appuie sur orderServiceClient pour obtenir un numéro de commande.

Le orderServiceClient est une API externe et est également gérée par Spring.

Remplacer le Bean d'origine

L'étape suivante consiste à remplacer le Bean d'origine.

@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());
    }
}

L'interface CommandLineRunner est implémentée et la méthode run() peut être appelée une fois l'initialisation du conteneur Spring terminée.

Le code est très simple. Pour faire simple, déterminez d'abord de quel environnement il s'agit. Après tout, à l'exception de l'environnement local, tout le reste doit réellement appeler le service distant.

L'étape suivante consiste à obtenir le bean et à le supprimer manuellement.

L'étape clé :

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

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

Créez un nouvel objet OrderServiceClient et enregistrez-le manuellement dans le conteneur Spring.

Le premier morceau de code utilise l'API de PowerMockito.mock, qui peut créer un objet proxy afin que toutes les méthodes appelant OrderServiceClient reviennent par défaut.

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

Testez-le, quand on ne le remplace pas, on appelle l'interface à l'instant et le local ne démarre pas OrderService :

Partage de compétences pratiques sur SpringBoot

Le secours n'étant pas configuré, une erreur sera signalée, indiquant que le service est introuvable.

Lors du remplacement du bean :

Partage de compétences pratiques sur SpringBoot

Aucune erreur n'a été signalée lors de la nouvelle demande et notre retour par défaut a été obtenu.

Partage de compétences pratiques sur SpringBoot

Vous découvrirez également grâce au journal que OrderServiceClient a finalement été mandaté par Mock et n'appellera pas la vraie méthode.

Configurer le cryptage

L'étape suivante consiste à configurer le cryptage, qui doit être considéré comme une fonction de base.

Par exemple, certains comptes et mots de passe de nos fichiers de configuration doivent être stockés sous forme de texte chiffré.

Cette fois, un composant open source est utilisé pour implémenter le cryptage et le décryptage, et il est très SpringBoot convivial et ne nécessite que quelques morceaux de code pour être complété.

  • 首先根据加密密码将需要加密的配置加密为密文。

  • 替换原本明文保存的配置。

  • 再使用时进行解密。

使用该包也只需要引入一个依赖即可:

<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

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer