- 投稿日:2020-04-04T20:00:11+09:00
lombokでデフォルトコンストラクタが無くてNoSuchMethodException
凡ミスの記録。
lombokを使用して以下のコードを実行したところ、実行時エラーになった。
@Data @AllArgsConstructor public class Person { ...Caused by: java.lang.InstantiationException: kagamihoge.springbatchsample.Person at java.base/java.lang.Class.newInstance(Class.java:571) ~[na:na] at org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper.getBean(BeanWrapperFieldSetMapper.java:248) ~[spring-batch-infrastructure-4.2.1.RELEASE.jar:4.2.1.RELEASE] ... 53 common frames omitted Caused by: java.lang.NoSuchMethodException: kagamihoge.springbatchsample.Person.<init>() at java.base/java.lang.Class.getConstructor0(Class.java:3350) ~[na:na] at java.base/java.lang.Class.newInstance(Class.java:556) ~[na:na] ... 54 common frames omitted原因は、引数無しのデフォルトコンストラクタが無いのでリフレクションによるインスタンス生成に失敗していた。
というわけで、lombokで引数無しコンストラクタも生成するように指定した。
@Data @AllArgsConstructor @NoArgsConstructor public class Person { ..
- 投稿日:2020-04-04T19:13:04+09:00
Spring Boot 2 Filter内でSessionScopeBeanをDIする
前置き
最近Spring BootでWeb開発をしています。直接HttpSessionを利用する方法ではなく、できるだけ@SessionScopeでセッションを管理したいと思っています。Filter内で@SeesionScope Beanを参照する方法を調査しました。
構成
名前 バージョン macOS Catalina 10.15.4 IntelliJ IDEA 2019.3.4 (Community Edition) Java "11.0.2" 2019-01-15 Spring Boot 2.2.6 Kotlin 1.3.71 サンプルコードやプロジェクトをGitHubに公開しています。よろしければご覧ください。
結論
いろいろな情報があり調査した内容も後述しますが、最初に結論から書きます。
シンプルな構成であれば@Autowired
のみで実現可能でした。UserInfo.kt(@SessionScope)@Component @SessionScope data class UserInfo( var name: String? ) : SerializableSessionFilter.kt(OncePerRequestFilter)@Component class SessionFilter : OncePerRequestFilter() { // ControllerでDIするのと同様でした。 @Autowired private lateinit var userInfo: UserInfo override fun doFilterInternal(request: HttpServletRequest, response: HttpServletResponse, filterChain: FilterChain) { println("name: ${userInfo.name}") filterChain.doFilter(request, response) } }結論までの経緯
Spring Boot 2の書籍ではありませんが、Spring界隈では有名と思われるSpring徹底入門 Spring FrameworkによるJavaアプリケーション開発では
DelegatingFilterProxy
にフィルターを登録することをXMLで定義する方法が提案されていました。
そのため、まずDelegatingFilterProxy
を使う方法を試行することにしました。筆者はXMLで定義する方法を好まないので、Java Config(Kotlin)で書き直しました。SessionFilter.kt(OncePerRequestFilter)@Component("SessionFilter") // 名前を指定していました。 class SessionFilter : OncePerRequestFilter() { : : (結論で掲載したコードと同じ) : }WebInitializer.ktclass WebInitializer : AbstractAnnotationConfigDispatcherServletInitializer() { override fun getRootConfigClasses(): Array<Class<*>>? { return null } override fun getServletMappings(): Array<String> { return arrayOf("/") } override fun getServletFilters(): Array<Filter> { val dfp = DelegatingFilterProxy().apply { // SessionFilter.ktの@Componentで指定した名前を設定します。 setTargetBeanName("SessionFilter") } return arrayOf(dfp) } override fun getServletConfigClasses(): Array<Class<*>>? { return arrayOf(WebConfig::class.java) } }
FilterにDIできない
FAQをいくつか拝見して、上記のような対処方法が紹介されていることがありましたが、筆者の環境では結論のとおり、この記述がなくても目的を達成しました。
Spring MVCとSpring Boot 2の違いがあるのかもしれませんが、情報が少なすぎて調査しきれていません。終わりに
(決してマイナーなWebフレームワークではないと思いますが)他の有名なWebフレームワークと比較すると、Spring関連の情報は煩雑でレガシーなものが多いような印象を持ちました。そのため、何かのお役に立てたらいいなぁと思いまして、久しぶりに記事を投稿しました。
- 投稿日:2020-04-04T13:39:26+09:00
ずんどこプログラム
filename.rbpackage zundokoProgram; import java.util.Random; public class Zundoco_random { public static void main(String[] args) { Random random = new Random(); String[] zun_doko = { "ずん ", "どこ " }; String zundoko = new String(); while (!(zundoko.equals("ずん ずん ずん ずん どこ "))) { zundoko = ""; for (int i = 0; i < 5; i++) { String s = zun_doko[random.nextInt(2)]; // 変数sにランダムで選ばれた配列sh[0,1]のどちらか1文字が入る zundoko = zundoko.concat(s); // 変数scに変数sをくっつける } System.out.println(zundoko); } System.out.println("きよしぃいい!!!"); } }ずんどこプログラム初めて記念に投稿させていただきたい・・・!!
3日くらいかかりました。
- 投稿日:2020-04-04T11:20:28+09:00
Javaでsuperメソッドを呼び出す
はじめに
簡単なことからコツコツとjavaのアウトプットをします。
javaシルバーに合格することを目標に勉強中。superとは
スーパークラスのインスタンスや変数を参照する際に使用する。
superを用いての親クラスメソッドの呼び出し方
super.メソッド名
書いてみる
Main.java//スーパークラス class hoge { public void print() { System.out.println("hello from スーパークラス"); } } //子クラス class huga extends hoge { public void print() { System.out.println("hello from 子クラス"); } public void executePrint() { //子クラスのprint print(); //スーパークラスのprint super.print(); } } public class Main { public static void main(String[] args) { huga obj = new huga(); obj.executePrint(); } }実行結果
hello from 子クラス hello from スーパークラス子クラスから親クラスのメソッドを明示的に呼び出せていることが分かる。
おわりに
コンストラクタの場合は子クラスをインスタンス化すると
スーパークラスのコンストラクタ
→子クラスのコンストラクタ
が実行される。詳細は別の記事で書く予定。
参考文献
この記事は以下の情報を参考にして執筆しました。