这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战
1. 提问:怎么让一个接口通过不同的开发环境进行不同的sql操作?
全文用以区分的配置文件以
spring.profiles.active为例
首先,mapper层用spring注解@Value读取配置文件是不行的。编译不会错,但是通过注解写入的值必然为空。
2. 解决方案
把配置文件读到静态参数上面,然后Provider读取静态参数
2.1.什么时候才是一个写入静态参数的好时机呢?
在main方法的SpringApplication.run()之后,正好合适。
细心的同学可能发现了这个方法其实是有返回值的,返回了一个ConfigurableApplicationContext类。
这个context指的便是sping上下文,进去查源码,查看类描述
译:由大多数(如果不是所有)应用程序上下文实现的SPl接口。除了Applicationcontext接口中的应用程序上下文客户端方法外,还提供配置应用程序上下文的工具。这里封装了配置和生命周期方法,以避免让ApplicationContext客户端代码明显看到它们。目前的方法应该只在启动和关闭代码中使用。
继续从spring上下文里找环境变量
译:以可配置的形式返回此应用程序上下文的Environment,允许进一步定制。
那么我们便可以从spring环境里面取得想要的配置文件并写入静态变量了
2.2 开始编码测试
那么启动程序看一下,是否获得到了
这时候又有同学问了:“如果我们的配置文件读取了多个配置呢?这个string是不是就不干净啦?”
继续细看这个类,这就是答案,把每个激活的环境以集合的形式给你。
继续编码测试,这样就有更完善的方案来解决了。
3.剖析原理
3.1 代理与反射
spring注解的方式是在spring实现增强类的时候,把值注入进去的。那么值为空的情况就可以大胆猜测了: mybatis调用Provider类时用的是类本类,所以获取不到值。
验证时刻:“类和类不能一概而论”
![]()
3.2 深追底层
可以看到该类调用了.newInstance()方法
译: 创建由class对象表示的类的新实例。类被实例化,就像通过带有空参数列表的new表达式一样。注意,该方法传播由空构造函数抛出的任何异常,包括检查的异常。使用此方法可以有效地绕过编译器执行的编译时异常检查。构造函数。newInstance方法通过将构造函数抛出的任何异常包装在(checked)InvocationTargetException中来避免这个问题。
3.3 延展
看到了
.newInstance()方法,至少能够确定,在使用Mybatis的时候操作Provider的时候必须要一个public的空参构造器。