Practical SpringBoot Tips: Mocking External Dependencies and Encrypting Configuration
This article shares practical SpringBoot techniques for locally mocking external service dependencies and encrypting configuration properties, detailing step-by-step bean replacement using PowerMockito, configuration encryption with Jasypt, and accompanying code examples for seamless development without starting full distributed services.
In this tutorial the author presents two useful SpringBoot tricks: how to block external dependencies during local development and how to encrypt configuration values. The goal is to enable developers to run and test code without starting all distributed services.
Blocking external dependencies
When a project relies on services such as SpringCloud or Dubbo, developers often face the problem of needing many upstream services for local testing. Common approaches include starting all services locally, pointing the registry to a development environment, or pushing code to a dev environment. Each method has drawbacks like resource consumption, network dependency, or lack of debugging capability.
The proposed solution is to use the mocking technique already available in unit tests. By manually removing the original bean from the Spring container and registering a mock implementation, the application can run locally without the real external services.
@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;
}The replacement process consists of four steps:
Locate the bean that needs to be blocked (e.g., OrderServiceClient).
Remove the bean definition from the DefaultListableBeanFactory.
Create a mock instance using PowerMockito.mock that returns a predefined response.
Register the mock instance back into the bean factory.
Implementation example:
@Component
public class OrderMockServiceConfig implements CommandLineRunner {
private 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 factory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
OrderServiceClient client = factory.getBean(OrderServiceClient.class);
logger.info("======orderServiceClient {}=====", client.getClass());
factory.removeBeanDefinition(OrderServiceClient.class.getCanonicalName());
OrderServiceClient mockOrderApi = PowerMockito.mock(OrderServiceClient.class,
invocation -> BaseResponse.createSuccess(DateUtil.getLongTime() + "", "mock orderNo success"));
factory.registerSingleton(OrderServiceClient.class.getCanonicalName(), mockOrderApi);
logger.info("======mockOrderApi {}=====", mockOrderApi.getClass());
}
}This runner executes after the Spring context is initialized, replaces the real OrderServiceClient bean with a mock, and prevents calls to the actual remote service.
Configuration encryption
To protect sensitive data such as database usernames and passwords, the article introduces the jasypt-spring-boot-starter library. Adding a single Maven dependency enables encryption and decryption of property values.
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>1.14</version>
</dependency>A test can generate encrypted strings using the injected StringEncryptor:
@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 + "----------------");
}During application startup, the encrypted values are stored in the configuration file, and a custom BeanPostProcessor decrypts them before the DataSourceProperties bean is used.
@Component
public class DataSourceProcess implements BeanPostProcessor {
@Autowired
private StringEncryptor encryptor;
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof DataSourceProperties) {
DataSourceProperties props = (DataSourceProperties) bean;
props.setUsername(encryptor.decrypt(props.getUsername()));
props.setPassword(encryptor.decrypt(props.getPassword()));
return props;
}
return bean;
}
}The encrypted configuration can be supplied at runtime via JVM arguments, e.g.,
java -Djasypt.encryptor.password=password -jar target/jasypt-spring-boot-demo-0.0.1-SNAPSHOT.jar.
Both techniques allow developers to work locally with minimal setup, improve testability, and keep sensitive information safe.
Feel free to comment with more SpringBoot tips, and the source code is available at https://github.com/crossoverJie/springboot-cloud .
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
