前提・実現したいこと
只今、spring boot2にてaop機能を利用したメソッドのログ出力を実施しています。
ただ、MenuControllerをaop対象にした場合、menuService変数がnullになってしまいます。
aop対象外にするとオブジェクトが正常に参照されます。
できれば、MenuControllerをaop対象にしてログ出力したいと考えております。
発生している問題・エラーメッセージ
2021/11/09 16:03:16 WARN [http-nio-9210-exec-5] - Resolved [java.lang.NullPointerException]
該当のソースコード
java
1package jp.co.toraya.aop; 2 3import org.aspectj.lang.JoinPoint; 4import org.aspectj.lang.annotation.After; 5import org.aspectj.lang.annotation.AfterThrowing; 6import org.aspectj.lang.annotation.Aspect; 7import org.aspectj.lang.annotation.Before; 8import org.aspectj.lang.annotation.Pointcut; 9import org.slf4j.Logger; 10import org.springframework.stereotype.Component; 11 12 13@Aspect 14@Component 15public class LogAspct { 16 Logger logger = org.slf4j.LoggerFactory.getLogger(LogAspct.class); 17 18 // ~Controllerクラスとメソッドを対象にする 19 @Pointcut("execution(* *..*.*Controller.*(..))") 20 boolean loggingPattern() { 21 return true; 22 } 23 24 // 除外クラスを指定。 25 // aop対象にMenuControllerを指定すると52行目menuServiceがnullになってしまう。 26 // 原因不明。 27// @Pointcut("execution(* *..*.MenuController.*(..)) " + "|| execution(* *..*.ForwardController.*(..) )" + "") 28 @Pointcut("execution(* *..*.ForwardController.*(..) ) " ) 29 boolean ignorePattern() { 30 return true; 31 } 32 33 // AOP実装 34 @Before("loggingPattern() && !ignorePattern()") 35 public void startLog(JoinPoint jp) { 36 logger.info("メソッド開始 : " + jp.getSignature()); 37 } 38 39 // AOP実装 40 @After("loggingPattern() && ! ignorePattern()") 41 public void endLog(JoinPoint jp) { 42 logger.info("メソッド終了 : " + jp.getSignature()); 43 } 44 @AfterThrowing(value = "loggingPattern() && ! ignorePattern()", throwing = "e") 45 public void afterThrowing(Throwable e){ 46 // logger.info(e.getMessage()); 47 logger.warn("Caught Exception.", e); 48 } 49 50 51 52} 53
java
1package jp.co.toraya.controller; 2 3 4 5 6import java.util.Enumeration; 7import java.util.List; 8 9import javax.servlet.http.HttpSession; 10 11import org.springframework.beans.factory.annotation.Autowired; 12import org.springframework.security.core.Authentication; 13import org.springframework.security.core.context.SecurityContextHolder; 14import org.springframework.stereotype.Controller; 15import org.springframework.ui.Model; 16import org.springframework.web.bind.annotation.RequestMapping; 17import org.springframework.web.bind.annotation.RequestMethod; 18import org.springframework.web.bind.annotation.RequestParam; 19 20import jp.co.toraya.constants.TzzConstants; 21import jp.co.toraya.domain.KoyuMenuJoin; 22import jp.co.toraya.service.MenuService; 23import jp.co.toraya.service.MenuSub; 24import jp.co.toraya.service.Pankuzu; 25 26/** 27 * メニュー画面のコントローラクラス 28 * @author hogehoge 29 * 30 */ 31@Controller 32public class MenuController { 33 34 @Autowired 35 private MenuService menuService; // !!ここのmenuServiceがaop対象になるとnullになります。 36 @Autowired 37 HttpSession session; 38 39 /** 40 * ログイン成功時に呼び出されるメソッド。ホームリンク押下時呼ばれるメソッド。 41 * SecurityContextHolderから認証済みユーザの情報を取得しモデルへ追加する 42 * @param model リクエストスコープ上にオブジェクトを載せるためのmap 43 * @return menuページのViewName 44 */ 45 @RequestMapping("/menu") 46 private String init(Model model) { 47 Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 48 //Principalからログインユーザの情報を取得 49 String shainCd = auth.getName(); 50 51 // sidebarMenuのデータセット 52 List<KoyuMenuJoin> koyuMenuJoinList = menuService.setKoyuMenuJoinList(shainCd); 53 model.addAttribute("koyuMenuJoinList", koyuMenuJoinList); 54 55 // パンくずの削除 56 session.removeAttribute("pankuzuList"); 57 // springや、パンくず以外のセッションをメニューに戻った際は消す。 58 clearSession(); 59 return "menu"; 60 61 } 62 63 /** 64 * sidebarMenuのボタンが押された時の処理。 65 * @param model リクエストスコープ上にオブジェクトを載せるためのmap 66 * @return menuページのViewName 67 */ 68 @RequestMapping(value = "menu", params = "gyomuBunruiOyaNo", method = RequestMethod.GET) 69 private String clickedSidebarMenu(@RequestParam("gyomuBunruiOyaNo") String gyomuBunruiOyaNo 70 ,Model model) { 71 Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 72 //Principalからログインユーザの情報を取得 73 String shainCd = auth.getName(); 74 75 // sidebarMenuのデータセット 76 List<KoyuMenuJoin> koyuMenuJoinList = menuService.setKoyuMenuJoinList(shainCd); 77 model.addAttribute("koyuMenuJoinList", koyuMenuJoinList); 78 79 // メニューのmainのデータセット 80 List<MenuSub> menuSubList = menuService.setMenuSubList(shainCd, gyomuBunruiOyaNo); 81 model.addAttribute("menuSubList", menuSubList); 82 83 // パンくずリストの作成 84 List<Pankuzu> pankuzuList = menuService.setPankuzuList(gyomuBunruiOyaNo); 85 // パンくずをセッションスコープへ保持 86 session.setAttribute("pankuzuList", pankuzuList); 87 // springや、パンくず以外のセッションをメニューに戻った際は消す。 88 clearSession(); 89 // str 90 // 以下の処理を書いても、別のControllerのセッションを消してくれない。 91 // sessionStatus.setComplete(); 92 93 94 95 96 97 // end 98 return "menu"; 99 100 } 101 // springや、パンくず以外のセッションをメニューに戻った際は消す。 102 private void clearSession() { 103 for(Enumeration<String> enumeration = session.getAttributeNames();enumeration.hasMoreElements();) { 104 String attributeName = (String)enumeration.nextElement(); 105 // System.out.println("attributeName:" + attributeName); 106 if(!TzzConstants.NO_CLEAR_SESSION_ATTRIBUTE_NAME.contains(attributeName)) { 107 session.removeAttribute(attributeName); 108 System.out.println("削除する属性:" + attributeName); 109 } 110 } 111 } 112 113 114 115}
java
1package jp.co.toraya.service; 2 3import java.util.ArrayList; 4import java.util.List; 5 6import org.springframework.beans.factory.annotation.Autowired; 7import org.springframework.stereotype.Service; 8 9import jp.co.toraya.domain.KoyuMenuJoin; 10import jp.co.toraya.domain.KoyuMenuJoinPgm; 11import jp.co.toraya.domain.KoyuMenuJoinSub; 12import jp.co.toraya.domain.MenuOya; 13import jp.co.toraya.domain.Shain; 14import jp.co.toraya.mapper.KoyuMenuJoinMapper; 15import jp.co.toraya.mapper.MenuOyaMapper; 16import jp.co.toraya.mapper.ShainMapper; 17 18@Service 19public class MenuService { 20 @Autowired 21 KoyuMenuJoinMapper koyuMenuJoinMapper; 22 @Autowired 23 ShainMapper shainMapper; 24 @Autowired 25 MenuOyaMapper menuOyaMapper; 26 /** 27 * sidebarMenuのデータセット 28 * @param shainCd 社員コード 29 * @param gyomuBunruiOyaNo 業務分類親NO 30 * @return sidebarMenuのデータ 31 */ 32 public List<KoyuMenuJoin> setKoyuMenuJoinList(String shainCd) { 33 KoyuMenuJoin koyuMenuJoin = new KoyuMenuJoin(); 34 koyuMenuJoin.setGyomuBunruiOyaName("ホーム"); 35 Shain shain = shainMapper.findByShainCd(shainCd); 36 List<KoyuMenuJoin> koyuMenuJoinList = koyuMenuJoinMapper.findByKoyuMenuCd(shain.getKoyuMenuCd()); 37 koyuMenuJoinList.add(0, koyuMenuJoin); 38 return koyuMenuJoinList; 39 } 40 41 /** 42 * メニューのmainのデータをセット 43 * @param shainCd 社員コード 44 * @param gyomuBunruiOyaNo 業務分類親NO 45 * @return メニューのmainのデータ 46 */ 47 public List<MenuSub> setMenuSubList(String shainCd, String gyomuBunruiOyaNo) { 48 List<KoyuMenuJoinSub> koyuMenuJoinSubList = koyuMenuJoinMapper.findByKoyuMenuCdGyomuBunruiOyaNo( 49 shainMapper.findByShainCd(shainCd).getKoyuMenuCd(), 50 gyomuBunruiOyaNo 51 ); 52 MenuSub menuSub = null; 53 List<MenuSub> menuSubList = new ArrayList<MenuSub>(); 54 MenuProgram menuProgram = null; 55 List<MenuProgram> menuProgramList = null; 56 for (KoyuMenuJoinSub koyuMenuJoinSub : koyuMenuJoinSubList) { 57 menuSub = new MenuSub(); 58 menuSub.setGyomuBunruiKoCd(koyuMenuJoinSub.getGyomuBunruiKoCd()); 59 menuSub.setGyomuBunruiKoName(koyuMenuJoinSub.getGyomuBunruiKoName()); 60 61 menuProgramList = new ArrayList<MenuProgram>(); 62 List<KoyuMenuJoinPgm> koyuMenuJoinPgmList = 63 koyuMenuJoinMapper.findByKoyuMenuCdGyomuBunruiOyaNoGyomuBunruiKoNo( 64 shainMapper.findByShainCd(shainCd).getKoyuMenuCd(), 65 gyomuBunruiOyaNo, 66 koyuMenuJoinSub.getGyomuBunruiKoCd() 67 ); 68 for (KoyuMenuJoinPgm koyuMenuJoinPgm : koyuMenuJoinPgmList) { 69 menuProgram = new MenuProgram(); 70 menuProgram.setPrgCd(koyuMenuJoinPgm.getPgmId()); 71 menuProgram.setMenuHyojiName(koyuMenuJoinPgm.getPgmName()); 72 menuProgram.setUrl(koyuMenuJoinPgm.getUrl()); 73 menuProgram.setHikiCnt(koyuMenuJoinPgm.getHikiCnt()); 74 menuProgramList.add(menuProgram); 75 } 76 menuSub.setProgramList(menuProgramList); 77 menuSubList.add(menuSub); 78 } 79 return menuSubList; 80 } 81 82 /** 83 * パンくずリストの作成 84 * @param userId ユーザーID 85 * @param gyomuBunruiOyaNo 業務分類親NO 86 * @return メニューのmainのデータ 87 */ 88 public List<Pankuzu> setPankuzuList(String gyomuBunruiOyaNo) { 89 // パンくずの作成(セッションスコープへ保持) 90 ArrayList<Pankuzu> pankuzuList = new ArrayList<Pankuzu>(); 91 Pankuzu pankuzu = new Pankuzu(); 92 pankuzu.setUrl("menu"); 93 pankuzu.setHikiCnt(null); 94 pankuzu.setName("ホーム"); 95 pankuzuList.add(pankuzu); 96 97 pankuzu = new Pankuzu(); 98 pankuzu.setUrl("menu"); 99 pankuzu.setHikiCnt("?gyomuBunruiOyaNo=" + gyomuBunruiOyaNo); 100 MenuOya menuOya = menuOyaMapper.findByPrimaryKey(gyomuBunruiOyaNo); 101 pankuzu.setName(menuOya.getGyomuBunruiOyaName()); 102 pankuzuList.add(pankuzu); 103 return pankuzuList; 104 105 } 106 107} 108
試したこと
色々自身で調査した結果では、
・該当Serviceクラスをインターフェースにする。
・finalメソッドをやめる。
・privateでの参照から、publicへ変更する。
などの情報より色々試してみましたが、改善しませんでした。
お気づきの点がありましたらご指摘頂けます出ようか。
宜しくお願い致します。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。