Help
RSS
API
Feed
Maltego
Contact
Domain > backpaper0.github.io
×
More information on this domain is in
AlienVault OTX
Is this malicious?
Yes
No
DNS Resolutions
Date
IP Address
2015-09-28
23.235.46.133
(
ClassC
)
2015-10-26
199.27.76.133
(
ClassC
)
2018-04-21
151.101.193.147
(
ClassC
)
2018-04-21
151.101.65.147
(
ClassC
)
2024-07-07
185.199.111.153
(
ClassC
)
Port 80
HTTP/1.1 200 OKConnection: keep-aliveContent-Length: 45273Server: GitHub.comContent-Type: text/html; charsetutf-8permissions-policy: interest-cohort()Last-Modified: Fri, 02 Oct 2020 12:17:33 GMTAccess-Control-Allow-Origin: *ETag: 5f771a5d-b0d9expires: Sun, 07 Jul 2024 19:57:09 GMTCache-Control: max-age600x-proxy-cache: MISSX-GitHub-Request-Id: A57D:3FB0FC:FDF257:108C64F:668AF0BDAccept-Ranges: bytesAge: 0Date: Sun, 07 Jul 2024 19:47:09 GMTVia: 1.1 varnishX-Served-By: cache-bfi-krnt7300043-BFIX-Cache: MISSX-Cache-Hits: 0X-Timer: S1720381629.167567,VS0,VE82Vary: Accept-EncodingX-Fastly-Request-ID: aff6d89d826ff5f8b4d19a6ae8418d2e7352a362 !DOCTYPE html>!--if lt IE 7> html xmlnshttp://www.w3.org/1999/xhtml xmlns:oghttp://ogp.me/ns# xmlns:fbhttps://www.facebook.com/2008/fbml classno-js lt-ie9 lt-ie8 lt-ie7> !endif-->!--if IE 7> html xmlnshttp://www.w3.org/1999/xhtml xmlns:oghttp://ogp.me/ns# xmlns:fbhttps://www.facebook.com/2008/fbml classno-js lt-ie9 lt-ie8> !endif-->!--if IE 8> html xmlnshttp://www.w3.org/1999/xhtml xmlns:oghttp://ogp.me/ns# xmlns:fbhttps://www.facebook.com/2008/fbml classno-js lt-ie9> !endif-->!--if gt IE 8>!--> html xmlnshttp://www.w3.org/1999/xhtml xmlns:oghttp://ogp.me/ns# xmlns:fbhttps://www.facebook.com/2008/fbml classno-js> !--!endif--> head> meta charsetutf-8> meta http-equivX-UA-Compatible contentIEedge,chrome1> meta namedescription contentMy blog> meta nameviewport contentwidthdevice-width> title>Home — 裏紙/title> link relstylesheet href_static/normalize.css typetext/css> link relstylesheet href_static/sphinx.css typetext/css> link relstylesheet href_static/main.css typetext/css> link relstylesheet href_static/tinkerbelizehole.css typetext/css> link relstylesheet href_static/pygments.css typetext/css /> link relstylesheet href_static/font-awesome.min.css typetext/css> link relshortcut icon href_static/backpaper0.ico />!-- Load modernizr and JQuery --> script src_static/vendor/modernizr-2.6.2.min.js>/script> script src//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js>/script> script>window.jQuery || document.write(script src_static/vendor/jquery-1.8.2.min.js>\/script>)/script> script src_static/plugins.js>/script> script src_static/main.js>/script> link relsearch titleSearch hrefsearch.html />link relnext titleOlder hrefpage2.html />link relalternate typeapplication/rss+xml titleRSS hrefrss.html />script typetext/javascript> var DOCUMENTATION_OPTIONS { URL_ROOT: ./, VERSION: 1.7.2, COLLAPSE_INDEX: false, FILE_SUFFIX: .html, SOURCELINK_SUFFIX: .txt, HAS_SOURCE: true }; /script>script typetext/javascript src_static/underscore.js>/script>script typetext/javascript src_static/doctools.js>/script>/head> body roledocument> !--if lt IE 7> p classchromeframe>You are using an strong>outdated/strong> browser. Please a hrefhttp://browsehappy.com/>upgrade your browser/a> or a hrefhttp://www.google.com/chromeframe/?redirecttrue>activate Google Chrome Frame/a> to improve your experience./p> !endif--> div idcontainer>nav> ul> li classmain-nav> a href#>Home/a> /li> li classmain-nav> a hrefpages/about.html>これはなに?/a> /li> li classmain-nav> a hrefpages/ghosts.html>資料/a> /li> li> a hrefarchive.html>Archives/a> /li>li classquicklink>div classrss> a hrefrss.html titleSubscribe via RSS>span classfa fa-lg fa-rss>/span>/a> /div>/li>/ul> /nav> header rolebanner> hgroup> h1>a href#>裏紙/a>/h1>h2>I ❤️ BotW./h2>/hgroup> /header> div classmain-container rolemain>div classmain wrapper body clearfix>article>div classtimestamp postmeta> span>February 22, 2018/span> /div> div classsection> h1>a href2018/02/22/spring_proxy.html>Springのproxyとfinalメソッド、それからnull/a>/h1>blockquote classtwitter-tweet data-langja>p langja dirltr>SpringのRepositoryとComponentアノテ、動きに違いがあるのか、、br/>Repositoryだとフィールドがnullになってハマった/p>— こざけ (@s_kozake) a hrefhttps://twitter.com/s_kozake/status/964792731548631040?ref_srctwsrc%5Etfw>2018年2月17日/a>/blockquote>script async srchttps://platform.twitter.com/widgets.js charsetutf-8>{}/script>blockquote classtwitter-tweet data-langja>p langja dirltr>ようやく🍥Repositoryでフィールドの値がnullになる原因が分かった、、br/>メソッドをfinal指定してましたbr/>サブクラスベースのProxyではメソッドやクラスにfinalをつけてはいけないとあれほど_:(´ཀ`」 ∠):/p>— こざけ (@s_kozake) a hrefhttps://twitter.com/s_kozake/status/965462883864735744?ref_srctwsrc%5Etfw>2018年2月19日/a>/blockquote>script async srchttps://platform.twitter.com/widgets.js charsetutf-8>{}/script>blockquote classtwitter-tweet data-langja>p langja dirltr>ここら辺、どこか詳しい資料ありますか?br/>CGLIBを用いてサブクラスベースのProxyを実現している状況で、メソッドをfinalにした場合、内部でどのような状況になってnullのインスタンスを見るようになったかというbr/>まあ、そもそもfinal切るなって話なのですが/p>— こざけ (@s_kozake) a hrefhttps://twitter.com/s_kozake/status/965717257379659777?ref_srctwsrc%5Etfw>2018年2月19日/a>/blockquote>script async srchttps://platform.twitter.com/widgets.js charsetutf-8>{}/script>p>こざけさんがこんな感じでわちゃわちゃしていたので、詳しい資料はどこにあるか分からないけれど、なぜそうなったのか解説しようと思います。/p>p>なぜそうなるのか概ね理解していたけれど、理解していなかった点を調べる過程で私自身も学ぶことがあったので、正直こざけさんには調べるきっかけを作ってくれてありがとうございますという感じです!/p>div classsection idrepositoryproxy>h2>@Repositoryとproxy/h2>p>span classdocutils literal>span classpre>@Repository/span>/span> をクラスに付けると、そのクラスのproxyが作られます。/p>p>proxyてなんやねんって話ですが、これは実行時に生成される該当クラスのサブクラスで、他のコンポーネントにインジェクションされるのはこのproxyのインスタンスです。実際のクラスのインスタンスへはproxyのインスタンスを経由して委譲される仕組みになっています。/p>p>このproxyの仕組みには、コンポーネントの利用者がスコープを意識しなくてよくなるという利点があります。/p>p>どういうことか、順を追って見ていきましょう。/p>div classsection idproxydi>h3>proxyという概念が無いDIコンテナ/h3>p>DIコンテナにはスコープというものがあります。/p>p>これはコンポーネントのライフサイクルを表すもので、Webアプリで動くDIコンテナであれば「リクエストスコープ」や「セッションスコープ」を持っています。「リクエストスコープ」はその名の通りHTTPリクエストの開始から終了までの間に有効となるスコープです。「セッションスコープ」もその名の通りでセッションを開始してから破棄されるまでの間に有効となるスコープです。/p>p>では「セッションスコープのコンポーネント」から「リクエストスコープのコンポーネント」を使用することを考えてみましょう。コードで書くとこんな感じ。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classc1>//※これはSpringではない架空のDIコンテナのコード/span>span classnd>@SessionScope/span>span classkd>public/span> span classkd>class/span> span classnc>Hoge/span> span classp>{/span> span classnd>@Inject/span> span classkd>private/span> span classn>Fuga/span> span classn>fuga/span>span classp>;/span> span classkd>public/span> span classkt>void/span> span classnf>action/span>span classp>()/span> span classp>{/span> span classn>fuga/span>span classp>./span>span classna>process/span>span classp>();/span> span classp>}/span>span classp>}/span>span classnd>@RequestScope/span>span classkd>public/span> span classkd>class/span> span classnc>Fuga/span> span classp>{/span> span classc1>//フィールドやメソッドの定義は省略/span>span classp>}/span>/pre>/div>/div>p>この span classdocutils literal>span classpre>Hoge/span>/span> と span classdocutils literal>span classpre>Fuga/span>/span> を使った処理の流れは、/p>ol classarabic simple>li>HTTPリクエストを受け取る/li>li>セッションを作成する/li>li>span classdocutils literal>span classpre>Hoge/span>/span> のインスタンスを作成する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のインスタンスを作成する/li>li>span classdocutils literal>span classpre>Hoge/span>/span> に span classdocutils literal>span classpre>Fuga/span>/span> をインジェクションする/li>li>span classdocutils literal>span classpre>Hoge/span>/span> の span classdocutils literal>span classpre>action/span>/span> メソッドを実行する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> の span classdocutils literal>span classpre>process/span>/span> メソッドを実行する/li>li>HTTPリクエストが終了する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のインスタンスをDIコンテナから破棄する/li>li>HTTPレスポンスを返す/li>/ol>p>という感じ。/p>p>あんまり問題なさそうに見えますが、 span classdocutils literal>span classpre>Fuga/span>/span> の span classdocutils literal>span classpre>process/span>/span> メソッドが実行中に同じユーザーからもう一つHTTPリクエストが来たらどうなるでしょうか?/p>ol classarabic simple>li>HTTPリクエストAを受け取る/li>li>セッションを作成する/li>li>span classdocutils literal>span classpre>Hoge/span>/span> のインスタンスを作成する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のインスタンスを作成する(リクエストAのスコープ)/li>li>span classdocutils literal>span classpre>Hoge/span>/span> に span classdocutils literal>span classpre>Fuga/span>/span> をインジェクションする/li>li>span classdocutils literal>span classpre>Hoge/span>/span> の span classdocutils literal>span classpre>action/span>/span> メソッドを実行する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> の span classdocutils literal>span classpre>process/span>/span> メソッドを実行し始める/li>li>HTTPリクエストBを受け取る/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のインスタンスを作成する(リクエストBのスコープ)/li>li>span classdocutils literal>span classpre>Hoge/span>/span> に span classdocutils literal>span classpre>Fuga/span>/span> をインジェクションする……!?/li>/ol>p>とまあ、こんな感じで span classdocutils literal>span classpre>Hoge/span>/span> にインジェクションされる span classdocutils literal>span classpre>Fuga/span>/span> がバッティングするわけです。/p>p>そういうわけでproxyの無いDIコンテナでは、あるスコープのコンポーネントには、それよりも小さいスコープ(ライフサイクルが短いと言い換えても良さそう)のコンポーネントをインジェクションできませんでした。proxyが無くてこのような制約のあるDIコンテナとしてはSeasar2が挙げられます。/p>/div>div classsection idid1>h3>proxyがあるDIコンテナ/h3>p>先に述べた問題をproxyがどのように解決するのか見ていきましょう。/p>p>span classdocutils literal>span classpre>Fuga/span>/span> のproxyをコードで書くとこんな感じになります。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classc1>//実際には実行時にクラスファイルが生成されるのでソースコードは存在しない/span>span classc1>//あくまでもproxyのイメージ/span>span classkd>public/span> span classkd>class/span> span classnc>FugaProxy/span> span classkd>extends/span> span classn>Fuga/span> span classp>{/span> span classkd>private/span> span classn>Container/span> span classn>container/span>span classp>;/span> span classkd>public/span> span classkt>void/span> span classnf>process/span>span classp>()/span> span classp>{/span> span classn>Fuga/span> span classn>component/span> span classo>/span> span classn>container/span>span classp>./span>span classna>getComponent/span>span classp>(/span>span classn>Fuga/span>span classp>./span>span classna>class/span>span classp>);/span> span classn>component/span>span classp>./span>span classna>process/span>span classp>();/span> span classp>}/span>span classp>}/span>/pre>/div>/div>p>コード上のコメントにも書きましたが、proxyは実際には実行時にクラスファイル(というかインメモリ上にバイトコードのデータ)として生成されるのが普通なので、ソースコードはありません。コード例は雰囲気です。/p>p>コードを見てみると span classdocutils literal>span classpre>process/span>/span> メソッドが呼ばれるとDIコンテナからproxyではない実際の span classdocutils literal>span classpre>Foo/span>/span> インスタンスが取り出され、そのインスタンスの span classdocutils literal>span classpre>process/span>/span> メソッドが呼ばれています。/p>p>先ほどのproxyが無いDIコンテナで span classdocutils literal>span classpre>Fuga/span>/span> がバッティングしてしまったシナリオを、proxyがあるDIコンテナではどうなるか見てみましょう。/p>ol classarabic simple>li>HTTPリクエストAを受け取る/li>li>セッションを作成する/li>li>span classdocutils literal>span classpre>Hoge/span>/span> のインスタンスを作成する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のインスタンスを作成する(リクエストAのスコープ)/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のproxyを作成する/li>li>span classdocutils literal>span classpre>Hoge/span>/span> に span classdocutils literal>span classpre>Fuga/span>/span> のproxyをインジェクションする/li>li>span classdocutils literal>span classpre>Hoge/span>/span> の span classdocutils literal>span classpre>action/span>/span> メソッドを実行する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のproxyの span classdocutils literal>span classpre>process/span>/span> メソッドを実行し始める/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のproxy内でDIコンテナから実際の span classdocutils literal>span classpre>Fuga/span>/span> インスタンス(リクエストAのスコープ)を取り出して span classdocutils literal>span classpre>process/span>/span> メソッドを実行し始める/li>li>HTTPリクエストBを受け取る/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のインスタンスを作成する(リクエストBのスコープ)/li>li>span classdocutils literal>span classpre>Hoge/span>/span> の span classdocutils literal>span classpre>action/span>/span> メソッドを実行する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のproxyの span classdocutils literal>span classpre>process/span>/span> メソッドを実行し始める/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のproxy内でDIコンテナから実際の span classdocutils literal>span classpre>Fuga/span>/span> インスタンス(リクエストBのスコープ)を取り出して span classdocutils literal>span classpre>process/span>/span> メソッドを実行し始める/li>/ol>p>このようにproxyを経由してDIコンテナから異なる span classdocutils literal>span classpre>Fuga/span>/span> インスタンスを取り出して span classdocutils literal>span classpre>process/span>/span> メソッドを実行できました。/p>p>以上のことからproxyがあるDIコンテナではスコープを意識することなくインジェクションを行えることが分かりました。/p>/div>/div>div classsection idfinalnull>h2>finalメソッドからフィールドを参照したらnullになった理由/h2>p>当初の問題に戻りましょう。「 span classdocutils literal>span classpre>@Respository/span>/span> を付けたクラスの span classdocutils literal>span classpre>final/span>/span> なメソッドを実行するとインジェクションされたはずのフィールドへアクセスしたときに span classdocutils literal>span classpre>NullPointerException/span>/span> が発生した」という問題です。/p>p>次のコードを見てください。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classnd>@Repository/span>span classkd>public/span> span classkd>class/span> span classnc>Foo/span> span classp>{/span> span classnd>@Autowired/span> span classkd>private/span> span classn>Bar/span> span classn>bar/span>span classp>;/span> span classkd>public/span> span classn>String/span> span classnf>method1/span>span classp>()/span> span classp>{/span> span classk>return/span> span classn>String/span>span classp>./span>span classna>format/span>span classp>(/span>span classs>%s%n%s%n/span>span classp>,/span> span classn>bar/span>span classp>,/span> span classn>getClass/span>span classp>());/span> span classp>}/span> span classkd>public/span> span classkd>final/span> span classn>String/span> span classnf>method2/span>span classp>()/span> span classp>{/span> span classk>return/span> span classn>String/span>span classp>./span>span classna>format/span>span classp>(/span>span classs>%s%n%s%n/span>span classp>,/span> span classn>bar/span>span classp>,/span> span classn>getClass/span>span classp>());/span> span classp>}/span>span classp>}/span>/pre>/div>/div>p>span classdocutils literal>span classpre>method1/span>/span> と span classdocutils literal>span classpre>method2/span>/span> はどちらもフィールド span classdocutils literal>span classpre>bar/span>/span> と自分自身のクラスを文字列にして返しています。異なる点は span classdocutils literal>span classpre>method2/span>/span> は span classdocutils literal>span classpre>final/span>/span> であるということだけです。/p>p>span classdocutils literal>span classpre>method1/span>/span> の実行結果はこちら。/p>div classhighlight-none notranslate>div classhighlight>pre>span/>com.example.demo.Bar@1db75e25class com.example.demo.Foo/pre>/div>/div>p>span classdocutils literal>span classpre>method2/span>/span> の実行結果はこちら。/p>div classhighlight-none notranslate>div classhighlight>pre>span/>nullclass com.example.demo.Foo$$EnhancerBySpringCGLIB$$a65476ff/pre>/div>/div>p>当初の問題と同じように span classdocutils literal>span classpre>final/span>/span> な方の span classdocutils literal>span classpre>method2/span>/span> では span classdocutils literal>span classpre>bar/span>/span> が span classdocutils literal>span classpre>null/span>/span> になっていますね。/p>p>ただ、クラス名にも注目してください。span classdocutils literal>span classpre>method1/span>/span> では span classdocutils literal>span classpre>Foo/span>/span> となっていますが span classdocutils literal>span classpre>method2/span>/span> は span classdocutils literal>span classpre>Foo/span>/span> のproxyになっています。/p>p>ここで span classdocutils literal>span classpre>Foo/span>/span> のproxyがどうなっているのか、再び雰囲気でコードにしてみましょう。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classc1>//雰囲気/span>span classkd>public/span> span classkd>class/span> span classnc>Foo$$EnhancerBySpringCGLIB$$a65476ff/span> span classkd>extends/span> span classn>Foo/span> span classp>{/span> span classn>Container/span> span classn>container/span>span classp>;/span> span classnd>@Override/span> span classkd>public/span> span classn>String/span> span classnf>method1/span>span classp>()/span> span classp>{/span> span classn>Foo/span> span classn>component/span> span classo>/span> span classn>container/span>span classp>./span>span classna>getComponent/span>span classp>(/span>span classn>Foo/span>span classp>./span>span classna>class/span>span classp>);/span> span classk>return/span> span classn>component/span>span classp>./span>span classna>method1/span>span classp>();/span> span classp>}/span> span classc1>//method2はfinalなのでoverrideできない/span>span classp>}/span>/pre>/div>/div>p>ご覧の通り span classdocutils literal>span classpre>method1/span>/span> はコンテナから実際のインスタンスを取り出して委譲していますが、span classdocutils literal>span classpre>method2/span>/span> は span classdocutils literal>span classpre>final/span>/span> なため span classdocutils literal>span classpre>override/span>/span> できずに実際のインスタンスに委譲されることなく実行されてしまいます。/p>p>proxyは、コンテナから実際のインスタンスを取り出して委譲するものなので、proxyに対してコンポーネントをインジェクションする意味はありません。実際、元のクラスでインジェクション対象となっているフィールドはproxyでは span classdocutils literal>span classpre>null/span>/span> になります。/p>p>以上が、proxyが作られるクラスに定義された span classdocutils literal>span classpre>final/span>/span> メソッドがインジェクション対象のフィールドを参照している場合に span classdocutils literal>span classpre>NullPointerException/span>/span> になる理由です。/p>/div>div classsection idproxy>h2>コンストラクタインジェクションとproxy/h2>p>さて、ここからが私も初めて知った事柄になります。久しぶりにびっくりした。/p>p>次のようにコンストラクタインジェクションしているクラスを考えてみましょう。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classnd>@Repository/span>span classkd>public/span> span classkd>class/span> span classnc>Foo/span> span classp>{/span> span classkd>private/span> span classkd>final/span> span classn>Bar/span> span classn>bar/span>span classp>;/span> span classkd>public/span> span classnf>Foo/span>span classp>(/span>span classn>Bar/span> span classn>bar/span>span classp>)/span> span classp>{/span> span classk>this/span>span classp>./span>span classna>bar/span> span classo>/span> span classn>Objects/span>span classp>./span>span classna>requireNonNull/span>span classp>(/span>span classn>bar/span>span classp>);/span> span classp>}/span> span classkd>public/span> span classn>String/span> span classnf>method1/span>span classp>()/span> span classp>{/span> span classk>return/span> span classn>String/span>span classp>./span>span classna>format/span>span classp>(/span>span classs>%s%n%s%n/span>span classp>,/span> span classn>bar/span>span classp>,/span> span classn>getClass/span>span classp>());/span> span classp>}/span> span classkd>public/span> span classkd>final/span> span classn>String/span> span classnf>method2/span>span classp>()/span> span classp>{/span> span classk>return/span> span classn>String/span>span classp>./span>span classna>format/span>span classp>(/span>span classs>%s%n%s%n/span>span classp>,/span> span classn>bar/span>span classp>,/span> span classn>getClass/span>span classp>());/span> span classp>}/span>span classp>}/span>/pre>/div>/div>p>proxyの雰囲気コードはこんな感じ。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classc1>//雰囲気/span>span classkd>public/span> span classkd>class/span> span classnc>Foo$$EnhancerBySpringCGLIB$$a65476ff/span> span classkd>extends/span> span classn>Foo/span> span classp>{/span> span classn>Container/span> span classn>container/span>span classp>;/span> span classkd>public/span> span classnf>Foo$$EnhancerBySpringCGLIB$$a65476ff/span>span classp>(/span>span classn>Bar/span> span classn>bar/span>span classp>)/span> span classp>{/span> span classkd>super/span>span classp>(/span>span classn>bar/span>span classp>);/span> span classp>}/span> span classnd>@Override/span> span classkd>public/span> span classn>String/span> span classnf>method1/span>span classp>()/span> span classp>{/span> span classn>Foo/span> span classn>component/span> span classo>/span> span classn>container/span>span classp>./span>span classna>getComponent/span>span classp>(/span>span classn>Foo/span>span classp>./span>span classna>class/span>span classp>);/span> span classk>return/span> span classn>component/span>span classp>./span>span classna>method1/span>span classp>();/span> span classp>}/span> span classc1>//method2はfinalなのでoverrideできない/span>span classp>}/span>/pre>/div>/div>p>この場合、生成されるproxyのコンストラクタ引数 span classdocutils literal>span classpre>bar/span>/span> には何が入るのでしょうか?/p>p>先に述べた通り、proxyのインジェクション対象フィールドにはインジェクションする意味はありません。かと言って span classdocutils literal>span classpre>null/span>/span> を渡すとスーパークラスのコンストラクタで span classdocutils literal>span classpre>Objects.requireNonNull/span>/span> によって span classdocutils literal>span classpre>NullPointerException/span>/span> がスローされます。/p>p>それではSpringはproxyをインスタンス化するときに何を渡すのでしょうか?/p>p>色々とがんばってソースコードを追っかけた末に分かったのですが、コンストラクタを呼ばずにインスタンス化していました。何を言っているのか分かりませんね?/p>p>proxyのインスタンス化にはObjenesisというライブラリの次のクラスが使われていました。(実際には span classdocutils literal>span classpre>org.springframework.objenesis/span>/span> にrepackageされています)/p>ul classsimple>li>a classreference external hrefhttps://github.com/easymock/objenesis/blob/2.6/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java>https://github.com/easymock/objenesis/blob/2.6/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java/a>/li>/ul>p>クラスのJavadocに次の記載があります。/p>blockquote>div>Instantiates an object, WITHOUT calling it’s constructor, using internal sun.reflect.ReflectionFactory/div>/blockquote>p>お、おう……!って感じですが、JDKのinternalなクラスを使ってコンストラクタを呼ばずにインスタンス化していました。だからフィールドが span classdocutils literal>span classpre>null/span>/span> だった、というわけですね。/p>p>コンストラクタ呼ばれないってどういうことだよ……と思いながら span classdocutils literal>span classpre>SunReflectionFactoryInstantiator/span>/span> を眺めていたら span classdocutils literal>span classpre>newConstructorForSerialization/span>/span> というメソッド名が出てきて、そういえばシリアライズされたオブジェクトをデシリアライズする時ってコンストラクタ呼ばれないんだっけ、とか雑な記憶で雑に思いました。とか書いておくと詳しい人がコメントくれるはずです。他力本願。/p>/div>div classsection idid2>h2>まとめ/h2>ul classsimple>li>DIコンテナにはproxyを経由してスコープを意識せずに使える機能がある/li>li>proxyは実行時にサブクラスを生成して実現するので span classdocutils literal>span classpre>final/span>/span> メソッドを使うとマズい/li>li>SpringではproxyはJDKのinternalなクラスを使用してコンストラクタ呼び出し無しにインスタンス化される(その結果フィールドが span classdocutils literal>span classpre>null/span>/span> になる)/li>/ul>p>こんな感じで、割と真っ黒な黒魔術に辿り着いた感があって楽しかったです。こざけさん、ありがとう!/p>div classsection idid3>h3>ちなみに/h3>blockquote classtwitter-tweet data-langja>p langja dirltr>警告みたいなの欲しいですねー/p>— opengl-8080 (@opengl_8080) a hrefhttps://twitter.com/opengl_8080/status/965788137967386624?ref_srctwsrc%5Etfw>2018年2月20日/a>/blockquote>script async srchttps://platform.twitter.com/widgets.js charsetutf-8>{}/script>p>span classdocutils literal>span classpre>INFO/span>/span> レベルですが、ログは出ているみたいです。/p>div classhighlight-none notranslate>div classhighlight>pre>span/>018-02-22 22:22:14.298 INFO 25770 --- restartedMain o.s.aop.framework.CglibAopProxy : Final method public final java.lang.String com.example.demo.Foo.method2() cannot get proxied via CGLIB: Calls to this method will NOT be routed to the target instance and might lead to NPEs against uninitialized fields in the proxy instance./pre>/div>/div>/div>/div> /div> div classpostmeta> div classauthor> span>Posted by うらがみ/span> /div> div classtags> span> Tags: a hreftags/java.html>Java/a>/span> /div> /div>div classseparator post_separator>/div>div classtimestamp postmeta> span>April 17, 2017/span> /div> div classsection> h1>a href2017/04/17/acrobook.html>「Java本格入門」を読んだ/a>/h1>p>a classreference external hrefhttps://twitter.com/cero_t>せろさん/a>に献本して貰いました。ありがとうございます!/p>ul classsimple>li>a classreference external hrefhttp://gihyo.jp/book/2017/978-4-7741-8909-3>Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで:書籍案内|技術評論社/a>/li>/ul>p>この本はJavaの入門書ではありますが「本格」と付いているだけあって、/p>ul classsimple>li>コレクションの実装に踏み込んでどの場面でどの実装を使うべきか/li>li>span classdocutils literal>span classpre>Map#computeIfAbsent/span>/span> の現場あるあるな使い方/li>li>正規表現関連のオブジェクト( span classdocutils literal>span classpre>Pattern/span>/span> 、 span classdocutils literal>span classpre>Matcher/span>/span> )と span classdocutils literal>span classpre>String/span>/span> のメソッドの使い分け/li>/ul>p>など、実践的な内容が含まれています。/p>p>また、Java 8を前提として書かれてはいますが、ファイル操作に関してはJava 6までのやり方( span classdocutils literal>span classpre>java.io/span>/span> )とJava 7以降のやり方( span classdocutils literal>span classpre>java.nio.file/span>/span> )が、日時操作に関してはJava 7までのやり方( span classdocutils literal>span classpre>java.util.Date/span>/span> 、 span classdocutils literal>span classpre>java.util.Calendar/span>/span> )とJava 8以降のやり方( span classdocutils literal>span classpre>java.time/span>/span> )が両方書かれています。趣味プログラミングならいつでも最新のバージョンを使っていれば良いですが、仕事では案件によっては保守だけに徹しており古いやり方でコードを読み書きする必要がある場合もあるでしょう。この本ならレガシーと最新のどちらのやり方も学ぶ事ができます。/p>p>他にも、文法的に許可されてはいるが実践的な観点から書かない方が良いコードを教えてくれたり、インターフェースと抽象クラスの良い使い分け方を示してくれたり、執筆陣の知識・経験を元に書かれていることが単なる初心者向けの入門書とは異なるところだと感じました。/p>p>私の感覚でいうと、まったくの新人ではなく現場に出て2年目あるいは3年目ぐらいがこの本を読むのに適したレベルかな、と思います。/p>div classsection idid3>h2>間違いと思われる記述/h2>p>いくつか間違いがあったので挙げておこうと思います。/p>div classsection idid4>h3>35ページ、 span classdocutils literal>span classpre>>>/span>/span> 演算子の説明/h3>blockquote>div>正負の符号を表すビットは保持し、それ以外の空いたビットは0埋めする。/div>/blockquote>p>右方向の算術シフトは空いたビットを0埋めするのではなく、符号と同じビットで埋めます。/p>/div>div classsection idid5>h3>82ページ、インターフェースの説明/h3>blockquote>div>インターフェースは必ずpublicになるため、インターフェース名の前に書くpublicは省略することができます。/div>/blockquote>p>インターフェース名の前の span classdocutils literal>span classpre>public/span>/span> を省略するとパッケージプライベートになります。/p>p>また、ネストしたインターフェースは span classdocutils literal>span classpre>private/span>/span> にすることもできます。/p>/div>div classsection idid6>h3>156ページ、メソッド参照の文法/h3>p>これは間違いというより、表の内容が足りていないと思われます。/p>p>staticメソッドを参照する記法のひとつとして次のものを挙げています。/p>blockquote>div>{クラス名}::{メソッド名}/div>/blockquote>p>でもこれ、場合によってはインスタンスのメソッドを参照する記法としても使えます。/p>p>例えば、次のようなコードです。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classc1>//{クラス名}::{メソッド名}の記法でインスタンスのメソッドを参照している/span>span classn>ToIntFunction/span>span classo></span>span classn>String/span>span classo>>/span> span classn>f/span> span classo>/span> span classn>String/span>span classp>::/span>span classn>length/span>span classp>;/span>span classkt>int/span> span classn>i/span> span classo>/span> span classn>f/span>span classp>./span>span classna>applyAsInt/span>span classp>(/span>span classs>foobar/span>span classp>);/span>/pre>/div>/div>/div>div classsection idid7>h3>197ページ、ラムダ式内での例外について/h3>blockquote>div>ラムダの中に記述した処理で例外が発生する可能性があります。それが検査例外だった場合は、捕捉しないと、コンパイルエラーが発生します。/div>/blockquote>p>Stream APIで使われるラムダ式、つまり span classdocutils literal>span classpre>Function/span>/span> や span classdocutils literal>span classpre>Predicate/span>/span> であればそうですが、例えば span classdocutils literal>span classpre>Callable/span>/span> のラムダ式であれば span classdocutils literal>span classpre>call/span>/span> メソッドは span classdocutils literal>span classpre>throws/span> span classpre>Exception/span>/span> と宣言されているのでspan classdocutils literal>span classpre>Exception/span>/span> を span classdocutils literal>span classpre>catch/span>/span> する必要はありません。/p>/div>div classsection idid8>h3>その他の軽い間違い/h3>p>108ページ、フィボナッチ数を求める定義とコードが書かれていますが、定義を見ると span classdocutils literal>span classpre>F0/span> span classpre>/span> span classpre>0/span> span classpre>F1/span> span classpre>/span> span classpre>1/span> span classpre>Fn/span> span classpre>/span> span classpre>.../span>/span>となっていますが、直後に記載されている昔ながらの span classdocutils literal>span classpre>for/span>/span> ループを使ったコードは span classdocutils literal>span classpre>i/span> span classpre></span> span classpre>1/span>/span> のときに span classdocutils literal>span classpre>1/span>/span> を代入しているので、定義とコードが合ってないですね。/p>p>それと134ページ、「Mapインターフェースでの要素の取得、変換」に値の集合を取得するメソッドとして span classdocutils literal>span classpre>valueSet/span>/span>が挙げられていますが span classdocutils literal>span classpre>values/span>/span> の間違いだと思います。なお、 span classdocutils literal>span classpre>values/span>/span> の戻り値は集合( span classdocutils literal>span classpre>Set/span>/span> )ではなくコレクション( span classdocutils literal>span classpre>Collection/span>/span> )です。/p>p>あと、めっちゃ細かいところで言うと、183ページにAutoClosable、Closableという記述がありますが、正しくはAutoCloseable、Closeableです。(めっちゃ分かりづらいですが……)/p>/div>/div>div classsection idid9>h2>まとめ/h2>p>このようにいくつか間違いと思われる記述もありましたが、これらは前半の章(文法の解説などのまさに入門的な章)に集中していました。/p>p>読み進めるにつれてより実践的な内容が増えており、現場で使える知識を付けることができるのではないでしょうか。/p>/div> /div> div classpostmeta> div classauthor> span>Posted by うらがみ/span> /div> div classtags> span> Tags: a hreftags/java.html>Java/a>, a hreftags/bookreview.html>BookReview/a>/span> /div> /div>div classarchive_link> a hrefarchive.html> — Blog Archive — /a> /div>ul classrelated clearfix> li classleft>/li> li classright>a hrefpage2.html>Older/a> » /li> /ul>/article>aside classsidebar>section>div classwidget> h1>Recent Posts/h1> ul>li> a href2018/02/22/spring_proxy.html>Springのproxyとfinalメソッド、それからnull/a> /li>li> a href2017/04/17/acrobook.html>「Java本格入門」を読んだ/a> /li>li> a href2016/12/31/good_bye_2016.html>2016年ふりかえり/a> /li>li> a href2016/12/01/wife_peropero.html>世界の中心で愛を叫んだうらがみ/a> /li>li> a href2016/10/09/scala_ks.html>Scala関西Summit 2016へ参加・登壇したぞ! #scala_ks/a> /li>li> a href2016/10/01/unreachable_statements.html>セミコロンレスJavaで戻り値のあるメソッドを定義する(ただし返ってこない)の解説/a> /li>li> a href2016/09/11/githubwww.html>GitHubで毎日草生やし続ける運動を終了する/a> /li>li> a href2016/09/06/private_method.html>privateメソッドについての思いの変遷/a> /li>li> a href2016/07/12/doma_tokyo.html>東京でDoma勉強会やったぞ!!! #doma_tokyo/a> /li>li> a href2016/06/12/slider.html>関Javaで使ってたスマホでスライドめくるやつ/a> /li>/ul>/div>/section>section>div classwidget idsearchbox rolesearch> h1>a href#searchbox>Search/a>/h1> form actionsearch.html methodget> input typetext nameq /> button typesubmit>span classfa fa-search>/span>/button> /form>/div>/section>/aside>/div> !-- #main -->/div> !-- #main-container --> div classfooter-container rolecontentinfo>footer classwrapper>© Copyright 2013-2020, うらがみ. Powered by a hrefhttp://www.tinkerer.me/ target_blank>Tinkerer/a> and a hrefhttp://sphinx.pocoo.org/ target_blank>Sphinx/a>. a hrefhttps://pypi.python.org/pypi/sphinxjp.themes.tinkerbelizehole target_blank>This theme/a> is originally designed by a hrefhttp://naoiwata.github.com/ target_blank>naoiwata/a>./footer>/div> !-- footer-container --> /div> !--! end of #container -->!--if lt IE 7 > script src//ajax.googleapis.com/ajax/libs/chrome-frame/1.0.3/CFInstall.min.js>/script> script>window.attachEvent(onload,function(){CFInstall.check({mode:overlay})})/script> !endif--> /body>/html>
Port 443
HTTP/1.1 200 OKConnection: keep-aliveContent-Length: 45273Server: GitHub.comContent-Type: text/html; charsetutf-8permissions-policy: interest-cohort()Last-Modified: Fri, 02 Oct 2020 12:17:33 GMTAccess-Control-Allow-Origin: *ETag: 5f771a5d-b0d9expires: Sun, 07 Jul 2024 19:57:09 GMTCache-Control: max-age600x-proxy-cache: MISSX-GitHub-Request-Id: 236D:1E3933:FC9916:1076F7E:668AF0BDAccept-Ranges: bytesAge: 0Date: Sun, 07 Jul 2024 19:47:09 GMTVia: 1.1 varnishX-Served-By: cache-bfi-kbfi7400074-BFIX-Cache: MISSX-Cache-Hits: 0X-Timer: S1720381629.310874,VS0,VE82Vary: Accept-EncodingX-Fastly-Request-ID: 0cdc80dc6a9d8efd144a82ab82a393f2184fce72 !DOCTYPE html>!--if lt IE 7> html xmlnshttp://www.w3.org/1999/xhtml xmlns:oghttp://ogp.me/ns# xmlns:fbhttps://www.facebook.com/2008/fbml classno-js lt-ie9 lt-ie8 lt-ie7> !endif-->!--if IE 7> html xmlnshttp://www.w3.org/1999/xhtml xmlns:oghttp://ogp.me/ns# xmlns:fbhttps://www.facebook.com/2008/fbml classno-js lt-ie9 lt-ie8> !endif-->!--if IE 8> html xmlnshttp://www.w3.org/1999/xhtml xmlns:oghttp://ogp.me/ns# xmlns:fbhttps://www.facebook.com/2008/fbml classno-js lt-ie9> !endif-->!--if gt IE 8>!--> html xmlnshttp://www.w3.org/1999/xhtml xmlns:oghttp://ogp.me/ns# xmlns:fbhttps://www.facebook.com/2008/fbml classno-js> !--!endif--> head> meta charsetutf-8> meta http-equivX-UA-Compatible contentIEedge,chrome1> meta namedescription contentMy blog> meta nameviewport contentwidthdevice-width> title>Home — 裏紙/title> link relstylesheet href_static/normalize.css typetext/css> link relstylesheet href_static/sphinx.css typetext/css> link relstylesheet href_static/main.css typetext/css> link relstylesheet href_static/tinkerbelizehole.css typetext/css> link relstylesheet href_static/pygments.css typetext/css /> link relstylesheet href_static/font-awesome.min.css typetext/css> link relshortcut icon href_static/backpaper0.ico />!-- Load modernizr and JQuery --> script src_static/vendor/modernizr-2.6.2.min.js>/script> script src//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js>/script> script>window.jQuery || document.write(script src_static/vendor/jquery-1.8.2.min.js>\/script>)/script> script src_static/plugins.js>/script> script src_static/main.js>/script> link relsearch titleSearch hrefsearch.html />link relnext titleOlder hrefpage2.html />link relalternate typeapplication/rss+xml titleRSS hrefrss.html />script typetext/javascript> var DOCUMENTATION_OPTIONS { URL_ROOT: ./, VERSION: 1.7.2, COLLAPSE_INDEX: false, FILE_SUFFIX: .html, SOURCELINK_SUFFIX: .txt, HAS_SOURCE: true }; /script>script typetext/javascript src_static/underscore.js>/script>script typetext/javascript src_static/doctools.js>/script>/head> body roledocument> !--if lt IE 7> p classchromeframe>You are using an strong>outdated/strong> browser. Please a hrefhttp://browsehappy.com/>upgrade your browser/a> or a hrefhttp://www.google.com/chromeframe/?redirecttrue>activate Google Chrome Frame/a> to improve your experience./p> !endif--> div idcontainer>nav> ul> li classmain-nav> a href#>Home/a> /li> li classmain-nav> a hrefpages/about.html>これはなに?/a> /li> li classmain-nav> a hrefpages/ghosts.html>資料/a> /li> li> a hrefarchive.html>Archives/a> /li>li classquicklink>div classrss> a hrefrss.html titleSubscribe via RSS>span classfa fa-lg fa-rss>/span>/a> /div>/li>/ul> /nav> header rolebanner> hgroup> h1>a href#>裏紙/a>/h1>h2>I ❤️ BotW./h2>/hgroup> /header> div classmain-container rolemain>div classmain wrapper body clearfix>article>div classtimestamp postmeta> span>February 22, 2018/span> /div> div classsection> h1>a href2018/02/22/spring_proxy.html>Springのproxyとfinalメソッド、それからnull/a>/h1>blockquote classtwitter-tweet data-langja>p langja dirltr>SpringのRepositoryとComponentアノテ、動きに違いがあるのか、、br/>Repositoryだとフィールドがnullになってハマった/p>— こざけ (@s_kozake) a hrefhttps://twitter.com/s_kozake/status/964792731548631040?ref_srctwsrc%5Etfw>2018年2月17日/a>/blockquote>script async srchttps://platform.twitter.com/widgets.js charsetutf-8>{}/script>blockquote classtwitter-tweet data-langja>p langja dirltr>ようやく🍥Repositoryでフィールドの値がnullになる原因が分かった、、br/>メソッドをfinal指定してましたbr/>サブクラスベースのProxyではメソッドやクラスにfinalをつけてはいけないとあれほど_:(´ཀ`」 ∠):/p>— こざけ (@s_kozake) a hrefhttps://twitter.com/s_kozake/status/965462883864735744?ref_srctwsrc%5Etfw>2018年2月19日/a>/blockquote>script async srchttps://platform.twitter.com/widgets.js charsetutf-8>{}/script>blockquote classtwitter-tweet data-langja>p langja dirltr>ここら辺、どこか詳しい資料ありますか?br/>CGLIBを用いてサブクラスベースのProxyを実現している状況で、メソッドをfinalにした場合、内部でどのような状況になってnullのインスタンスを見るようになったかというbr/>まあ、そもそもfinal切るなって話なのですが/p>— こざけ (@s_kozake) a hrefhttps://twitter.com/s_kozake/status/965717257379659777?ref_srctwsrc%5Etfw>2018年2月19日/a>/blockquote>script async srchttps://platform.twitter.com/widgets.js charsetutf-8>{}/script>p>こざけさんがこんな感じでわちゃわちゃしていたので、詳しい資料はどこにあるか分からないけれど、なぜそうなったのか解説しようと思います。/p>p>なぜそうなるのか概ね理解していたけれど、理解していなかった点を調べる過程で私自身も学ぶことがあったので、正直こざけさんには調べるきっかけを作ってくれてありがとうございますという感じです!/p>div classsection idrepositoryproxy>h2>@Repositoryとproxy/h2>p>span classdocutils literal>span classpre>@Repository/span>/span> をクラスに付けると、そのクラスのproxyが作られます。/p>p>proxyてなんやねんって話ですが、これは実行時に生成される該当クラスのサブクラスで、他のコンポーネントにインジェクションされるのはこのproxyのインスタンスです。実際のクラスのインスタンスへはproxyのインスタンスを経由して委譲される仕組みになっています。/p>p>このproxyの仕組みには、コンポーネントの利用者がスコープを意識しなくてよくなるという利点があります。/p>p>どういうことか、順を追って見ていきましょう。/p>div classsection idproxydi>h3>proxyという概念が無いDIコンテナ/h3>p>DIコンテナにはスコープというものがあります。/p>p>これはコンポーネントのライフサイクルを表すもので、Webアプリで動くDIコンテナであれば「リクエストスコープ」や「セッションスコープ」を持っています。「リクエストスコープ」はその名の通りHTTPリクエストの開始から終了までの間に有効となるスコープです。「セッションスコープ」もその名の通りでセッションを開始してから破棄されるまでの間に有効となるスコープです。/p>p>では「セッションスコープのコンポーネント」から「リクエストスコープのコンポーネント」を使用することを考えてみましょう。コードで書くとこんな感じ。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classc1>//※これはSpringではない架空のDIコンテナのコード/span>span classnd>@SessionScope/span>span classkd>public/span> span classkd>class/span> span classnc>Hoge/span> span classp>{/span> span classnd>@Inject/span> span classkd>private/span> span classn>Fuga/span> span classn>fuga/span>span classp>;/span> span classkd>public/span> span classkt>void/span> span classnf>action/span>span classp>()/span> span classp>{/span> span classn>fuga/span>span classp>./span>span classna>process/span>span classp>();/span> span classp>}/span>span classp>}/span>span classnd>@RequestScope/span>span classkd>public/span> span classkd>class/span> span classnc>Fuga/span> span classp>{/span> span classc1>//フィールドやメソッドの定義は省略/span>span classp>}/span>/pre>/div>/div>p>この span classdocutils literal>span classpre>Hoge/span>/span> と span classdocutils literal>span classpre>Fuga/span>/span> を使った処理の流れは、/p>ol classarabic simple>li>HTTPリクエストを受け取る/li>li>セッションを作成する/li>li>span classdocutils literal>span classpre>Hoge/span>/span> のインスタンスを作成する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のインスタンスを作成する/li>li>span classdocutils literal>span classpre>Hoge/span>/span> に span classdocutils literal>span classpre>Fuga/span>/span> をインジェクションする/li>li>span classdocutils literal>span classpre>Hoge/span>/span> の span classdocutils literal>span classpre>action/span>/span> メソッドを実行する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> の span classdocutils literal>span classpre>process/span>/span> メソッドを実行する/li>li>HTTPリクエストが終了する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のインスタンスをDIコンテナから破棄する/li>li>HTTPレスポンスを返す/li>/ol>p>という感じ。/p>p>あんまり問題なさそうに見えますが、 span classdocutils literal>span classpre>Fuga/span>/span> の span classdocutils literal>span classpre>process/span>/span> メソッドが実行中に同じユーザーからもう一つHTTPリクエストが来たらどうなるでしょうか?/p>ol classarabic simple>li>HTTPリクエストAを受け取る/li>li>セッションを作成する/li>li>span classdocutils literal>span classpre>Hoge/span>/span> のインスタンスを作成する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のインスタンスを作成する(リクエストAのスコープ)/li>li>span classdocutils literal>span classpre>Hoge/span>/span> に span classdocutils literal>span classpre>Fuga/span>/span> をインジェクションする/li>li>span classdocutils literal>span classpre>Hoge/span>/span> の span classdocutils literal>span classpre>action/span>/span> メソッドを実行する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> の span classdocutils literal>span classpre>process/span>/span> メソッドを実行し始める/li>li>HTTPリクエストBを受け取る/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のインスタンスを作成する(リクエストBのスコープ)/li>li>span classdocutils literal>span classpre>Hoge/span>/span> に span classdocutils literal>span classpre>Fuga/span>/span> をインジェクションする……!?/li>/ol>p>とまあ、こんな感じで span classdocutils literal>span classpre>Hoge/span>/span> にインジェクションされる span classdocutils literal>span classpre>Fuga/span>/span> がバッティングするわけです。/p>p>そういうわけでproxyの無いDIコンテナでは、あるスコープのコンポーネントには、それよりも小さいスコープ(ライフサイクルが短いと言い換えても良さそう)のコンポーネントをインジェクションできませんでした。proxyが無くてこのような制約のあるDIコンテナとしてはSeasar2が挙げられます。/p>/div>div classsection idid1>h3>proxyがあるDIコンテナ/h3>p>先に述べた問題をproxyがどのように解決するのか見ていきましょう。/p>p>span classdocutils literal>span classpre>Fuga/span>/span> のproxyをコードで書くとこんな感じになります。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classc1>//実際には実行時にクラスファイルが生成されるのでソースコードは存在しない/span>span classc1>//あくまでもproxyのイメージ/span>span classkd>public/span> span classkd>class/span> span classnc>FugaProxy/span> span classkd>extends/span> span classn>Fuga/span> span classp>{/span> span classkd>private/span> span classn>Container/span> span classn>container/span>span classp>;/span> span classkd>public/span> span classkt>void/span> span classnf>process/span>span classp>()/span> span classp>{/span> span classn>Fuga/span> span classn>component/span> span classo>/span> span classn>container/span>span classp>./span>span classna>getComponent/span>span classp>(/span>span classn>Fuga/span>span classp>./span>span classna>class/span>span classp>);/span> span classn>component/span>span classp>./span>span classna>process/span>span classp>();/span> span classp>}/span>span classp>}/span>/pre>/div>/div>p>コード上のコメントにも書きましたが、proxyは実際には実行時にクラスファイル(というかインメモリ上にバイトコードのデータ)として生成されるのが普通なので、ソースコードはありません。コード例は雰囲気です。/p>p>コードを見てみると span classdocutils literal>span classpre>process/span>/span> メソッドが呼ばれるとDIコンテナからproxyではない実際の span classdocutils literal>span classpre>Foo/span>/span> インスタンスが取り出され、そのインスタンスの span classdocutils literal>span classpre>process/span>/span> メソッドが呼ばれています。/p>p>先ほどのproxyが無いDIコンテナで span classdocutils literal>span classpre>Fuga/span>/span> がバッティングしてしまったシナリオを、proxyがあるDIコンテナではどうなるか見てみましょう。/p>ol classarabic simple>li>HTTPリクエストAを受け取る/li>li>セッションを作成する/li>li>span classdocutils literal>span classpre>Hoge/span>/span> のインスタンスを作成する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のインスタンスを作成する(リクエストAのスコープ)/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のproxyを作成する/li>li>span classdocutils literal>span classpre>Hoge/span>/span> に span classdocutils literal>span classpre>Fuga/span>/span> のproxyをインジェクションする/li>li>span classdocutils literal>span classpre>Hoge/span>/span> の span classdocutils literal>span classpre>action/span>/span> メソッドを実行する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のproxyの span classdocutils literal>span classpre>process/span>/span> メソッドを実行し始める/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のproxy内でDIコンテナから実際の span classdocutils literal>span classpre>Fuga/span>/span> インスタンス(リクエストAのスコープ)を取り出して span classdocutils literal>span classpre>process/span>/span> メソッドを実行し始める/li>li>HTTPリクエストBを受け取る/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のインスタンスを作成する(リクエストBのスコープ)/li>li>span classdocutils literal>span classpre>Hoge/span>/span> の span classdocutils literal>span classpre>action/span>/span> メソッドを実行する/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のproxyの span classdocutils literal>span classpre>process/span>/span> メソッドを実行し始める/li>li>span classdocutils literal>span classpre>Fuga/span>/span> のproxy内でDIコンテナから実際の span classdocutils literal>span classpre>Fuga/span>/span> インスタンス(リクエストBのスコープ)を取り出して span classdocutils literal>span classpre>process/span>/span> メソッドを実行し始める/li>/ol>p>このようにproxyを経由してDIコンテナから異なる span classdocutils literal>span classpre>Fuga/span>/span> インスタンスを取り出して span classdocutils literal>span classpre>process/span>/span> メソッドを実行できました。/p>p>以上のことからproxyがあるDIコンテナではスコープを意識することなくインジェクションを行えることが分かりました。/p>/div>/div>div classsection idfinalnull>h2>finalメソッドからフィールドを参照したらnullになった理由/h2>p>当初の問題に戻りましょう。「 span classdocutils literal>span classpre>@Respository/span>/span> を付けたクラスの span classdocutils literal>span classpre>final/span>/span> なメソッドを実行するとインジェクションされたはずのフィールドへアクセスしたときに span classdocutils literal>span classpre>NullPointerException/span>/span> が発生した」という問題です。/p>p>次のコードを見てください。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classnd>@Repository/span>span classkd>public/span> span classkd>class/span> span classnc>Foo/span> span classp>{/span> span classnd>@Autowired/span> span classkd>private/span> span classn>Bar/span> span classn>bar/span>span classp>;/span> span classkd>public/span> span classn>String/span> span classnf>method1/span>span classp>()/span> span classp>{/span> span classk>return/span> span classn>String/span>span classp>./span>span classna>format/span>span classp>(/span>span classs>%s%n%s%n/span>span classp>,/span> span classn>bar/span>span classp>,/span> span classn>getClass/span>span classp>());/span> span classp>}/span> span classkd>public/span> span classkd>final/span> span classn>String/span> span classnf>method2/span>span classp>()/span> span classp>{/span> span classk>return/span> span classn>String/span>span classp>./span>span classna>format/span>span classp>(/span>span classs>%s%n%s%n/span>span classp>,/span> span classn>bar/span>span classp>,/span> span classn>getClass/span>span classp>());/span> span classp>}/span>span classp>}/span>/pre>/div>/div>p>span classdocutils literal>span classpre>method1/span>/span> と span classdocutils literal>span classpre>method2/span>/span> はどちらもフィールド span classdocutils literal>span classpre>bar/span>/span> と自分自身のクラスを文字列にして返しています。異なる点は span classdocutils literal>span classpre>method2/span>/span> は span classdocutils literal>span classpre>final/span>/span> であるということだけです。/p>p>span classdocutils literal>span classpre>method1/span>/span> の実行結果はこちら。/p>div classhighlight-none notranslate>div classhighlight>pre>span/>com.example.demo.Bar@1db75e25class com.example.demo.Foo/pre>/div>/div>p>span classdocutils literal>span classpre>method2/span>/span> の実行結果はこちら。/p>div classhighlight-none notranslate>div classhighlight>pre>span/>nullclass com.example.demo.Foo$$EnhancerBySpringCGLIB$$a65476ff/pre>/div>/div>p>当初の問題と同じように span classdocutils literal>span classpre>final/span>/span> な方の span classdocutils literal>span classpre>method2/span>/span> では span classdocutils literal>span classpre>bar/span>/span> が span classdocutils literal>span classpre>null/span>/span> になっていますね。/p>p>ただ、クラス名にも注目してください。span classdocutils literal>span classpre>method1/span>/span> では span classdocutils literal>span classpre>Foo/span>/span> となっていますが span classdocutils literal>span classpre>method2/span>/span> は span classdocutils literal>span classpre>Foo/span>/span> のproxyになっています。/p>p>ここで span classdocutils literal>span classpre>Foo/span>/span> のproxyがどうなっているのか、再び雰囲気でコードにしてみましょう。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classc1>//雰囲気/span>span classkd>public/span> span classkd>class/span> span classnc>Foo$$EnhancerBySpringCGLIB$$a65476ff/span> span classkd>extends/span> span classn>Foo/span> span classp>{/span> span classn>Container/span> span classn>container/span>span classp>;/span> span classnd>@Override/span> span classkd>public/span> span classn>String/span> span classnf>method1/span>span classp>()/span> span classp>{/span> span classn>Foo/span> span classn>component/span> span classo>/span> span classn>container/span>span classp>./span>span classna>getComponent/span>span classp>(/span>span classn>Foo/span>span classp>./span>span classna>class/span>span classp>);/span> span classk>return/span> span classn>component/span>span classp>./span>span classna>method1/span>span classp>();/span> span classp>}/span> span classc1>//method2はfinalなのでoverrideできない/span>span classp>}/span>/pre>/div>/div>p>ご覧の通り span classdocutils literal>span classpre>method1/span>/span> はコンテナから実際のインスタンスを取り出して委譲していますが、span classdocutils literal>span classpre>method2/span>/span> は span classdocutils literal>span classpre>final/span>/span> なため span classdocutils literal>span classpre>override/span>/span> できずに実際のインスタンスに委譲されることなく実行されてしまいます。/p>p>proxyは、コンテナから実際のインスタンスを取り出して委譲するものなので、proxyに対してコンポーネントをインジェクションする意味はありません。実際、元のクラスでインジェクション対象となっているフィールドはproxyでは span classdocutils literal>span classpre>null/span>/span> になります。/p>p>以上が、proxyが作られるクラスに定義された span classdocutils literal>span classpre>final/span>/span> メソッドがインジェクション対象のフィールドを参照している場合に span classdocutils literal>span classpre>NullPointerException/span>/span> になる理由です。/p>/div>div classsection idproxy>h2>コンストラクタインジェクションとproxy/h2>p>さて、ここからが私も初めて知った事柄になります。久しぶりにびっくりした。/p>p>次のようにコンストラクタインジェクションしているクラスを考えてみましょう。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classnd>@Repository/span>span classkd>public/span> span classkd>class/span> span classnc>Foo/span> span classp>{/span> span classkd>private/span> span classkd>final/span> span classn>Bar/span> span classn>bar/span>span classp>;/span> span classkd>public/span> span classnf>Foo/span>span classp>(/span>span classn>Bar/span> span classn>bar/span>span classp>)/span> span classp>{/span> span classk>this/span>span classp>./span>span classna>bar/span> span classo>/span> span classn>Objects/span>span classp>./span>span classna>requireNonNull/span>span classp>(/span>span classn>bar/span>span classp>);/span> span classp>}/span> span classkd>public/span> span classn>String/span> span classnf>method1/span>span classp>()/span> span classp>{/span> span classk>return/span> span classn>String/span>span classp>./span>span classna>format/span>span classp>(/span>span classs>%s%n%s%n/span>span classp>,/span> span classn>bar/span>span classp>,/span> span classn>getClass/span>span classp>());/span> span classp>}/span> span classkd>public/span> span classkd>final/span> span classn>String/span> span classnf>method2/span>span classp>()/span> span classp>{/span> span classk>return/span> span classn>String/span>span classp>./span>span classna>format/span>span classp>(/span>span classs>%s%n%s%n/span>span classp>,/span> span classn>bar/span>span classp>,/span> span classn>getClass/span>span classp>());/span> span classp>}/span>span classp>}/span>/pre>/div>/div>p>proxyの雰囲気コードはこんな感じ。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classc1>//雰囲気/span>span classkd>public/span> span classkd>class/span> span classnc>Foo$$EnhancerBySpringCGLIB$$a65476ff/span> span classkd>extends/span> span classn>Foo/span> span classp>{/span> span classn>Container/span> span classn>container/span>span classp>;/span> span classkd>public/span> span classnf>Foo$$EnhancerBySpringCGLIB$$a65476ff/span>span classp>(/span>span classn>Bar/span> span classn>bar/span>span classp>)/span> span classp>{/span> span classkd>super/span>span classp>(/span>span classn>bar/span>span classp>);/span> span classp>}/span> span classnd>@Override/span> span classkd>public/span> span classn>String/span> span classnf>method1/span>span classp>()/span> span classp>{/span> span classn>Foo/span> span classn>component/span> span classo>/span> span classn>container/span>span classp>./span>span classna>getComponent/span>span classp>(/span>span classn>Foo/span>span classp>./span>span classna>class/span>span classp>);/span> span classk>return/span> span classn>component/span>span classp>./span>span classna>method1/span>span classp>();/span> span classp>}/span> span classc1>//method2はfinalなのでoverrideできない/span>span classp>}/span>/pre>/div>/div>p>この場合、生成されるproxyのコンストラクタ引数 span classdocutils literal>span classpre>bar/span>/span> には何が入るのでしょうか?/p>p>先に述べた通り、proxyのインジェクション対象フィールドにはインジェクションする意味はありません。かと言って span classdocutils literal>span classpre>null/span>/span> を渡すとスーパークラスのコンストラクタで span classdocutils literal>span classpre>Objects.requireNonNull/span>/span> によって span classdocutils literal>span classpre>NullPointerException/span>/span> がスローされます。/p>p>それではSpringはproxyをインスタンス化するときに何を渡すのでしょうか?/p>p>色々とがんばってソースコードを追っかけた末に分かったのですが、コンストラクタを呼ばずにインスタンス化していました。何を言っているのか分かりませんね?/p>p>proxyのインスタンス化にはObjenesisというライブラリの次のクラスが使われていました。(実際には span classdocutils literal>span classpre>org.springframework.objenesis/span>/span> にrepackageされています)/p>ul classsimple>li>a classreference external hrefhttps://github.com/easymock/objenesis/blob/2.6/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java>https://github.com/easymock/objenesis/blob/2.6/main/src/main/java/org/objenesis/instantiator/sun/SunReflectionFactoryInstantiator.java/a>/li>/ul>p>クラスのJavadocに次の記載があります。/p>blockquote>div>Instantiates an object, WITHOUT calling it’s constructor, using internal sun.reflect.ReflectionFactory/div>/blockquote>p>お、おう……!って感じですが、JDKのinternalなクラスを使ってコンストラクタを呼ばずにインスタンス化していました。だからフィールドが span classdocutils literal>span classpre>null/span>/span> だった、というわけですね。/p>p>コンストラクタ呼ばれないってどういうことだよ……と思いながら span classdocutils literal>span classpre>SunReflectionFactoryInstantiator/span>/span> を眺めていたら span classdocutils literal>span classpre>newConstructorForSerialization/span>/span> というメソッド名が出てきて、そういえばシリアライズされたオブジェクトをデシリアライズする時ってコンストラクタ呼ばれないんだっけ、とか雑な記憶で雑に思いました。とか書いておくと詳しい人がコメントくれるはずです。他力本願。/p>/div>div classsection idid2>h2>まとめ/h2>ul classsimple>li>DIコンテナにはproxyを経由してスコープを意識せずに使える機能がある/li>li>proxyは実行時にサブクラスを生成して実現するので span classdocutils literal>span classpre>final/span>/span> メソッドを使うとマズい/li>li>SpringではproxyはJDKのinternalなクラスを使用してコンストラクタ呼び出し無しにインスタンス化される(その結果フィールドが span classdocutils literal>span classpre>null/span>/span> になる)/li>/ul>p>こんな感じで、割と真っ黒な黒魔術に辿り着いた感があって楽しかったです。こざけさん、ありがとう!/p>div classsection idid3>h3>ちなみに/h3>blockquote classtwitter-tweet data-langja>p langja dirltr>警告みたいなの欲しいですねー/p>— opengl-8080 (@opengl_8080) a hrefhttps://twitter.com/opengl_8080/status/965788137967386624?ref_srctwsrc%5Etfw>2018年2月20日/a>/blockquote>script async srchttps://platform.twitter.com/widgets.js charsetutf-8>{}/script>p>span classdocutils literal>span classpre>INFO/span>/span> レベルですが、ログは出ているみたいです。/p>div classhighlight-none notranslate>div classhighlight>pre>span/>018-02-22 22:22:14.298 INFO 25770 --- restartedMain o.s.aop.framework.CglibAopProxy : Final method public final java.lang.String com.example.demo.Foo.method2() cannot get proxied via CGLIB: Calls to this method will NOT be routed to the target instance and might lead to NPEs against uninitialized fields in the proxy instance./pre>/div>/div>/div>/div> /div> div classpostmeta> div classauthor> span>Posted by うらがみ/span> /div> div classtags> span> Tags: a hreftags/java.html>Java/a>/span> /div> /div>div classseparator post_separator>/div>div classtimestamp postmeta> span>April 17, 2017/span> /div> div classsection> h1>a href2017/04/17/acrobook.html>「Java本格入門」を読んだ/a>/h1>p>a classreference external hrefhttps://twitter.com/cero_t>せろさん/a>に献本して貰いました。ありがとうございます!/p>ul classsimple>li>a classreference external hrefhttp://gihyo.jp/book/2017/978-4-7741-8909-3>Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで:書籍案内|技術評論社/a>/li>/ul>p>この本はJavaの入門書ではありますが「本格」と付いているだけあって、/p>ul classsimple>li>コレクションの実装に踏み込んでどの場面でどの実装を使うべきか/li>li>span classdocutils literal>span classpre>Map#computeIfAbsent/span>/span> の現場あるあるな使い方/li>li>正規表現関連のオブジェクト( span classdocutils literal>span classpre>Pattern/span>/span> 、 span classdocutils literal>span classpre>Matcher/span>/span> )と span classdocutils literal>span classpre>String/span>/span> のメソッドの使い分け/li>/ul>p>など、実践的な内容が含まれています。/p>p>また、Java 8を前提として書かれてはいますが、ファイル操作に関してはJava 6までのやり方( span classdocutils literal>span classpre>java.io/span>/span> )とJava 7以降のやり方( span classdocutils literal>span classpre>java.nio.file/span>/span> )が、日時操作に関してはJava 7までのやり方( span classdocutils literal>span classpre>java.util.Date/span>/span> 、 span classdocutils literal>span classpre>java.util.Calendar/span>/span> )とJava 8以降のやり方( span classdocutils literal>span classpre>java.time/span>/span> )が両方書かれています。趣味プログラミングならいつでも最新のバージョンを使っていれば良いですが、仕事では案件によっては保守だけに徹しており古いやり方でコードを読み書きする必要がある場合もあるでしょう。この本ならレガシーと最新のどちらのやり方も学ぶ事ができます。/p>p>他にも、文法的に許可されてはいるが実践的な観点から書かない方が良いコードを教えてくれたり、インターフェースと抽象クラスの良い使い分け方を示してくれたり、執筆陣の知識・経験を元に書かれていることが単なる初心者向けの入門書とは異なるところだと感じました。/p>p>私の感覚でいうと、まったくの新人ではなく現場に出て2年目あるいは3年目ぐらいがこの本を読むのに適したレベルかな、と思います。/p>div classsection idid3>h2>間違いと思われる記述/h2>p>いくつか間違いがあったので挙げておこうと思います。/p>div classsection idid4>h3>35ページ、 span classdocutils literal>span classpre>>>/span>/span> 演算子の説明/h3>blockquote>div>正負の符号を表すビットは保持し、それ以外の空いたビットは0埋めする。/div>/blockquote>p>右方向の算術シフトは空いたビットを0埋めするのではなく、符号と同じビットで埋めます。/p>/div>div classsection idid5>h3>82ページ、インターフェースの説明/h3>blockquote>div>インターフェースは必ずpublicになるため、インターフェース名の前に書くpublicは省略することができます。/div>/blockquote>p>インターフェース名の前の span classdocutils literal>span classpre>public/span>/span> を省略するとパッケージプライベートになります。/p>p>また、ネストしたインターフェースは span classdocutils literal>span classpre>private/span>/span> にすることもできます。/p>/div>div classsection idid6>h3>156ページ、メソッド参照の文法/h3>p>これは間違いというより、表の内容が足りていないと思われます。/p>p>staticメソッドを参照する記法のひとつとして次のものを挙げています。/p>blockquote>div>{クラス名}::{メソッド名}/div>/blockquote>p>でもこれ、場合によってはインスタンスのメソッドを参照する記法としても使えます。/p>p>例えば、次のようなコードです。/p>div classhighlight-java notranslate>div classhighlight>pre>span/>span classc1>//{クラス名}::{メソッド名}の記法でインスタンスのメソッドを参照している/span>span classn>ToIntFunction/span>span classo></span>span classn>String/span>span classo>>/span> span classn>f/span> span classo>/span> span classn>String/span>span classp>::/span>span classn>length/span>span classp>;/span>span classkt>int/span> span classn>i/span> span classo>/span> span classn>f/span>span classp>./span>span classna>applyAsInt/span>span classp>(/span>span classs>foobar/span>span classp>);/span>/pre>/div>/div>/div>div classsection idid7>h3>197ページ、ラムダ式内での例外について/h3>blockquote>div>ラムダの中に記述した処理で例外が発生する可能性があります。それが検査例外だった場合は、捕捉しないと、コンパイルエラーが発生します。/div>/blockquote>p>Stream APIで使われるラムダ式、つまり span classdocutils literal>span classpre>Function/span>/span> や span classdocutils literal>span classpre>Predicate/span>/span> であればそうですが、例えば span classdocutils literal>span classpre>Callable/span>/span> のラムダ式であれば span classdocutils literal>span classpre>call/span>/span> メソッドは span classdocutils literal>span classpre>throws/span> span classpre>Exception/span>/span> と宣言されているのでspan classdocutils literal>span classpre>Exception/span>/span> を span classdocutils literal>span classpre>catch/span>/span> する必要はありません。/p>/div>div classsection idid8>h3>その他の軽い間違い/h3>p>108ページ、フィボナッチ数を求める定義とコードが書かれていますが、定義を見ると span classdocutils literal>span classpre>F0/span> span classpre>/span> span classpre>0/span> span classpre>F1/span> span classpre>/span> span classpre>1/span> span classpre>Fn/span> span classpre>/span> span classpre>.../span>/span>となっていますが、直後に記載されている昔ながらの span classdocutils literal>span classpre>for/span>/span> ループを使ったコードは span classdocutils literal>span classpre>i/span> span classpre></span> span classpre>1/span>/span> のときに span classdocutils literal>span classpre>1/span>/span> を代入しているので、定義とコードが合ってないですね。/p>p>それと134ページ、「Mapインターフェースでの要素の取得、変換」に値の集合を取得するメソッドとして span classdocutils literal>span classpre>valueSet/span>/span>が挙げられていますが span classdocutils literal>span classpre>values/span>/span> の間違いだと思います。なお、 span classdocutils literal>span classpre>values/span>/span> の戻り値は集合( span classdocutils literal>span classpre>Set/span>/span> )ではなくコレクション( span classdocutils literal>span classpre>Collection/span>/span> )です。/p>p>あと、めっちゃ細かいところで言うと、183ページにAutoClosable、Closableという記述がありますが、正しくはAutoCloseable、Closeableです。(めっちゃ分かりづらいですが……)/p>/div>/div>div classsection idid9>h2>まとめ/h2>p>このようにいくつか間違いと思われる記述もありましたが、これらは前半の章(文法の解説などのまさに入門的な章)に集中していました。/p>p>読み進めるにつれてより実践的な内容が増えており、現場で使える知識を付けることができるのではないでしょうか。/p>/div> /div> div classpostmeta> div classauthor> span>Posted by うらがみ/span> /div> div classtags> span> Tags: a hreftags/java.html>Java/a>, a hreftags/bookreview.html>BookReview/a>/span> /div> /div>div classarchive_link> a hrefarchive.html> — Blog Archive — /a> /div>ul classrelated clearfix> li classleft>/li> li classright>a hrefpage2.html>Older/a> » /li> /ul>/article>aside classsidebar>section>div classwidget> h1>Recent Posts/h1> ul>li> a href2018/02/22/spring_proxy.html>Springのproxyとfinalメソッド、それからnull/a> /li>li> a href2017/04/17/acrobook.html>「Java本格入門」を読んだ/a> /li>li> a href2016/12/31/good_bye_2016.html>2016年ふりかえり/a> /li>li> a href2016/12/01/wife_peropero.html>世界の中心で愛を叫んだうらがみ/a> /li>li> a href2016/10/09/scala_ks.html>Scala関西Summit 2016へ参加・登壇したぞ! #scala_ks/a> /li>li> a href2016/10/01/unreachable_statements.html>セミコロンレスJavaで戻り値のあるメソッドを定義する(ただし返ってこない)の解説/a> /li>li> a href2016/09/11/githubwww.html>GitHubで毎日草生やし続ける運動を終了する/a> /li>li> a href2016/09/06/private_method.html>privateメソッドについての思いの変遷/a> /li>li> a href2016/07/12/doma_tokyo.html>東京でDoma勉強会やったぞ!!! #doma_tokyo/a> /li>li> a href2016/06/12/slider.html>関Javaで使ってたスマホでスライドめくるやつ/a> /li>/ul>/div>/section>section>div classwidget idsearchbox rolesearch> h1>a href#searchbox>Search/a>/h1> form actionsearch.html methodget> input typetext nameq /> button typesubmit>span classfa fa-search>/span>/button> /form>/div>/section>/aside>/div> !-- #main -->/div> !-- #main-container --> div classfooter-container rolecontentinfo>footer classwrapper>© Copyright 2013-2020, うらがみ. Powered by a hrefhttp://www.tinkerer.me/ target_blank>Tinkerer/a> and a hrefhttp://sphinx.pocoo.org/ target_blank>Sphinx/a>. a hrefhttps://pypi.python.org/pypi/sphinxjp.themes.tinkerbelizehole target_blank>This theme/a> is originally designed by a hrefhttp://naoiwata.github.com/ target_blank>naoiwata/a>./footer>/div> !-- footer-container --> /div> !--! end of #container -->!--if lt IE 7 > script src//ajax.googleapis.com/ajax/libs/chrome-frame/1.0.3/CFInstall.min.js>/script> script>window.attachEvent(onload,function(){CFInstall.check({mode:overlay})})/script> !endif--> /body>/html>
View on OTX
|
View on ThreatMiner
Please enable JavaScript to view the
comments powered by Disqus.
Data with thanks to
AlienVault OTX
,
VirusTotal
,
Malwr
and
others
. [
Sitemap
]