平时写完sql、业务代码都得重启整个spring 容器,现在spring越来越重,启动时间就超级长,得注册到注册中心,初始化各种组件,效率太低,至少好几分钟过去了,我们为何自己不自己写一个简易版的,帮助我们快速启动测试代码,在这里我实现了 连mybaties和feign的代理类,其他类如dubbo、kafka 、redis 客户端也可以类似实现。
一、模拟spring获取bean
public class ApplicationContext {
public static Object getBean(Class clazz) {
try {
Object obInstance = clazz.newInstance();
autowiseBean(obInstance);
return obInstance;
} catch (Exception e) {
System.out.println(e.toString());
}
return null;
}
public static void autowiseBean(Object obInstance) {
try {
Field[] fs = obInstance.getClass().getDeclaredFields();
for (Field f : fs) {
if (exitAnnotation(f, "Autowired") ) {
if (f.getType().getName().contains("Mapper")) {
Object ob = ObjectFactory.createMapperFactory(f.getType());
f.setAccessible(true);
f.set(obInstance, ob);
} else if (f.getType().getName().contains("Client")) {
Object ob = ObjectFactory.creatFeignClient(f.getType());
f.setAccessible(true);
f.set(obInstance, ob);
} else {
//接口类不能反射 待优化
Object ob = f.getType().getClass().newInstance();
f.setAccessible(true);
f.set(obInstance, ob);
autowiseBean(ob);
}
}
}
} catch (Exception e) {
System.out.println(e.toString());
}
}
public static Boolean exitAnnotation(Field f, String annotation) {
try {
Annotation[] as = f.getAnnotations();
for (Annotation a : as) {
if (a.annotationType().getName().contains(annotation))
return true;
}
} catch (Exception e) {
System.out.println(e.toString());
}
return false;
}
}
二、 创建动态类
public class ObjectFactory<T> {
private static DefaultSqlSession sqlSession;
private static Executor executor;
/**
* 配置
*/
public static Configuration configuration;
static {
try {
TimeZone newTimeZone = TimeZone.getTimeZone("Asia/Chongqi");
TimeZone.setDefault(newTimeZone);
//定义一个配置
configuration = new Configuration();
configuration.setCacheEnabled(false);
configuration.setLazyLoadingEnabled(false);
configuration.setAggressiveLazyLoading(true);
configuration.setDefaultStatementTimeout(1000);
//读取测试环境数据库配置
PropertySource propertySource = new ResourcePropertySource(new ClassPathResource("mp.generator.properties"));
UnpooledDataSource dataSource = new UnpooledDataSource();
//设置数据库链接
dataSource.setDriver(propertySource.getProperty("jdbc.driver.className").toString());
dataSource.setUrl(propertySource.getProperty("jdbc.url").toString());
dataSource.setUsername(propertySource.getProperty("jdbc.username").toString());
dataSource.setPassword(propertySource.getProperty("jdbc.password").toString());
//设置事务(测试设置事务不提交false)
Transaction transaction = new JdbcTransaction(dataSource, TransactionIsolationLevel.READ_COMMITTED, true);
//设置执行
executor = configuration.newExecutor(transaction);
configuration.setDatabaseId(propertySource.getProperty("jdbc.type").toString());
configuration.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);
Class<? extends Log> s = configuration.getLogImpl();
} catch (Exception e) {
e.printStackTrace();
}
}
public static <T> T createMapperFactory(Class c) {
try {
String fileName = c.getName().substring(c.getName().lastIndexOf(".") + 1) + ".xml";
new ClassPathResource("mp.generator.properties");
StringBuilder path=new StringBuilder("");
String dir=System.getProperty("user.dir")+"\\src\\main\\resources\\sqlMapper\\o";
//解析mapper文件
if(!getPath(dir,fileName,path)){
System.out.println("没有获取到文件");
}
String common ="sqlMapper/o/"+path+fileName;
Resource mapperResource = new ClassPathResource(common);
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperResource.getInputStream(), configuration, mapperResource.toString(), configuration.getSqlFragments());
xmlMapperBuilder.parse();
//直接实例化一个默认的sqlSession
//是做单元测试,那么没必要通过SqlSessionFactoryBuilder构造SqlSessionFactory,再来获取SqlSession
sqlSession = new DefaultSqlSession(configuration, executor, true);
MapperProxyFactory<T> mapperProxyFactory = new MapperProxyFactory<T>(c);
T mapper = mapperProxyFactory.newInstance(sqlSession);
return mapper;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
public static <T> T creatFeignClient(Class clazz) {
try {
PropertySource propertySource = new ResourcePropertySource(new ClassPathResource("mp.generator.properties"));
return (T) Feign.builder().encoder(new SpringEncoder(() ->
new HttpMessageConverters(new MappingJackson2HttpMessageConverter(new ObjectMapper())))).
decoder(new SpringDecoder(() ->
new HttpMessageConverters(new MappingJackson2HttpMessageConverter(new ObjectMapper())))).
options(new Request.Options(2000, 5000)).
contract(new SpringMvcContract()).target(clazz, propertySource.getProperty("FeignClienturl").toString());
} catch (Exception e) {
System.out.println(e.toString());
}
return null;
}
public static Boolean getPath(String dir, String fileName, StringBuilder path) throws Exception {
File file = new File(dir);
File[] lss = file.listFiles();
for (int i = 0; i < lss.length; i++) {
if (!lss[i].isDirectory() && lss[i].getName().equals(fileName)) {
return true;
}
else if (lss[i].isDirectory() && getPath(lss[i].getAbsolutePath(), fileName, path)) {
path.insert(0,lss[i].getName()+File.separator);
return true;
}
}
return false;
}
二、 快速测试
@Service
public class RiskLimitServiceImpl implements RiskLimitService {
private static Logger logger = LoggerFactory.getLogger(RiskLimitService.class);
@Autowired
private RiskLimitMapper riskLimitMapper;
@Autowired
private PricingFeignClient pricingFeignClient;
@Test
public void RiskLimit() {
RiskLimitServiceImpl riskLimit = (RiskLimitServiceImpl)ApplicationContext.getBean(RiskLimitServiceImpl.class);
RiskLimitParam params=new RiskLimitParam();
riskLimit.queryRiskLimitService(param);
}
}
在这里插入代码片