Kotlin Spring中@Repository结合JdbcTemplate使用异常原因问询
异常原因分析
核心区别
你之前对三个注解的认知基本正确,三者唯一的功能差异在于:Spring会为标注@Repository的类自动生成AOP代理,实现持久层异常转换逻辑——即将JDBC、JPA等原生持久化异常统一转换为Spring的DataAccessException体系,方便上层统一处理,而@Component、@Service默认不会触发这个代理生成逻辑。
两次报错的根因
1. 未加open时报UnsatisfiedDependencyException
Kotlin默认所有类都是final类型,Spring生成CGLIB代理的原理是继承目标类,final类无法被继承,因此代理创建失败,抛出依赖不满足异常。
2. 加open后报NullPointerException
Spring CGLIB创建代理实例时,会先调用父类(即你定义的MobileRepository)的无参构造方法生成代理对象,你的类仅声明了带JdbcTemplate参数的构造方法,代理创建过程中不会触发带参构造为jdbcTemplate赋值,最终调用时访问到的代理对象的jdbcTemplate属性未初始化,导致空指针。
解决方案
- 方案1:添加
org.jetbrains.kotlin.plugin.spring插件(Maven/Gradle都支持),该插件会自动为所有标注Spring组件注解的类添加open修饰,同时将构造注入的jdbcTemplate改为val类型,即可正常生成代理完成注入。 - 方案2:如果不需要持久层异常转换能力,保持使用
@Component注解即可,业务逻辑不受任何影响。 - 方案3:将构造器注入改为字段注入,给
jdbcTemplate属性添加@Autowired注解,避免代理创建时的初始化问题(该方案不符合Spring注入规范,不优先推荐)。
内容的提问来源于stack exchange,提问作者Sandro J
相关产品推荐
相关产品推荐

