はじめに
staticメソッド内でmybatis用のmapper interfaceを@Autowiredして使いたかった時の話。
もちろんそのままだとstaticメソッドから非staticメソッドの参照だしそもそもinterfaceだしで使うことは出来ないので、回避策が必要。
NGパターン
MyMapper.java
package com.my.mapper;
public interface PhoneInfoMapper {
int selectByHogeHuga(String hogeFuga);
}
MyMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.my.mapper.MyMapper">
<delete id="selectByHogeHuga" parameterType="java.lang.String" resultType="java.lang.String">
select count(*) from my_table where hoge_huga = #{hogeHuga,jdbcType=VARCHAR}
</delete>
</mapper>
MyClassService.java
package com.my.service;
import com.my.mapper;
@Service
public class MyClassService {
// 非static参照となるためコンパイルエラー
@Autowired
private MyMapper myMapper;
// 実態はnullなので実行時エラー
@Autowired
private static MyMapper myMapper;
public static void myMethod() {
String hogeHuga = "hoge huga";
String result = myMapper.selectByHogeHuga(hogeFuga);
}
OKパターン
MyClassService.java
package com.my.service;
import com.my.mapper;
@Service
public class MyClassService {
// static変数を用意
private static PhoneInfoMapper phoneInfoMapper;
// Spring Bootの起動時にsetter injectionでstatic変数にDI
@Autowired
private void setPhoneInfoMapper(PhoneInfoMapper phoneInfoMapper){
FirebaseCloudMessagingConfig.phoneInfoMapper = phoneInfoMapper;
}
public static void myMethod() {
String hogeHuga = "hoge huga";
String result = myMapper.selectByHogeHuga(hogeFuga);
}