解决问题
在开发或测试环境中某些依赖的服务不能使用,需要通过mock依赖服务。
解决思路
ByteBuddy + BeanPostProcessor + @Profile
在Bean初始化时通过ByteBuddy对方法返回值进行替换,通过@Profile指定执行环境。代码示例如下
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.matcher.ElementMatchers;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
@Component
@Profile("test")
public class ByteBuddyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof targetService) { //确认拦截的类
return mockData();
}
return bean;
}
private Object mockData() {
try {
return new ByteBuddy()
.subclass(targetService.class)
.method(ElementMatchers.named("targetMethod")) //要拦截的方法
.intercept(FixedValue.value(""))// 设置返回值
.make()
.load(getClass().getClassLoader())
.getLoaded()
.newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}