共有ライブラリを管理するために Sonatype の Nexus Repository Manager OSS を使用する ( その19 )( Spring Framework に依存するライブラリを作成する2 )
概要
- 今回の手順で確認できるのは以下の内容です。
- ksbysample-webapp-lending から RequestAndResponseLogger.java を持ってきて auto-configuration 関連の実装まで進めます。
参照したサイト・書籍
Pro Spring Boot
- 作者: Felipe Gutierrez
- 出版社/メーカー: Apress
- 発売日: 2016/05/21
- メディア: ペーパーバック
- この商品を含むブログを見る
- auto-configuration プロジェクトのサンプルとして Chapter 14 の「The journal-spring-boot-autoconfigure Project」を参考にしました。
Spring Framework Reference Documentation - 12. Spring AOP APIs - 12.3.2 Advice types in Spring
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop-api.html#aop-api-advice-types- MethodInterceptor インターフェースを実装しようとすると import 候補に
org.aopalliance.intercept.MethodInterceptor
とorg.springframework.cglib.proxy.MethodInterceptor
の2つが出て来るのですが、どちらを使用すればよいか分からなかったので、このページを参照しました。invoke メソッドが書かれていたのでorg.aopalliance.intercept.MethodInterceptor
を使用します。
- MethodInterceptor インターフェースを実装しようとすると import 候補に
Spring Boot Reference Guide - 43. Creating your own auto-configuration
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-auto-configuration.htmlSpring Boot Reference Guide - 64. Spring Boot Gradle plugin - 64.6 Repackage configuration
http://docs.spring.io/spring-boot/docs/current/reference/html/build-tool-plugins-gradle-plugin.html#build-tool-plugins-gradle-repackage-configuration
目次
- ksbysample-webapp-lending から RequestAndResponseLogger.java を持ってくる
- AutoConfiguration クラスを作成する
- META-INF/spring.factories を作成する
- build してみる
- ksbysample-library-depend-spring-1.0.0-RELEASE.jar の中を見てみる
手順
ksbysample-webapp-lending から RequestAndResponseLogger.java を持ってくる
src/main/java の下に ksbysample.library.dependspring.intercepter パッケージを作成します。
ksbysample-webapp-lending の RequestAndResponseLogger.java をコピーして src/main/java/ksbysample/library/dependspring/intercepter の下にペーストします。
使用するライブラリがないので build.gradle を リンク先のその1の内容 に変更します。変更後、Gradle projects View の左上にある「Refresh all Gradle projects」ボタンをクリックして反映します。
AutoConfiguration クラスを作成する
Spring Boot の spring-boot-autoconfigure プロジェクト を見ると AutoConfiguration 用の Bean を作成するクラスはクラス名の末尾に AutoConfiguration
が付けられているようなので、RequestAndResponseLoggerAutoConfiguration.java を作成します。
src/main/java/ksbysample/library/dependspring の下に config パッケージを作成します。
src/main/java/ksbysample/library/dependspring/config の下に RequestAndResponseLoggerAutoConfiguration.java を作成し、リンク先の内容 を記述します。
META-INF/spring.factories を作成する
src/main/resources の下に META-INF ディレクトリを作成します。
src/main/resources/META-INF の下に spring.factories を作成し、リンク先の内容 を記述します。
build してみる
clean タスク実行 → Rebuild Project 実行をした後、build タスクを実行します。
"FAILURE" の文字が出力され失敗しました。
IntelliJ IDEA のコンソールに出力された内容ではエラーの原因が分からないので、コマンドプロンプトから
--stacktrace
オプションを付けて build タスクを実行してみます。出力されたログを見た感じでは、以下の原因のようです。
- bootRepackage タスクで失敗している。
- main クラスがないため失敗している。
main クラスは作成しないのでどうすればよいか調べてみたところ、64.6 Repackage configuration に
enabled
という設定項目を見つけました。これを false に設定すれば bootRepackage タスクは実行されなくなるようです。build.gradle を リンク先のその2の内容 に変更します。変更後、Gradle projects View の左上にある「Refresh all Gradle projects」ボタンをクリックして反映します。
再度 clean タスク実行 → Rebuild Project 実行をした後、build タスクを実行します。今度は "BUILD SUCCESSFUL" が出力されて成功しました。
jar ファイルが作成されていることも確認できました。
ksbysample-library-depend-spring-1.0.0-RELEASE.jar の中を見てみる
ksbysample-library-depend-spring-1.0.0-RELEASE.jar を解凍してみると以下の構成でした。
ksbysample-library-depend-spring-1.0.0-RELEASE.jar ├ generated ├ ksbysample │ └ library │ └ dependspring │ ├ config │ │ └ RequestAndResponseLoggerAutoConfiguration.class │ └ intercepter │ └ RequestAndResponseLogger.class ├ META-INF │ ├ MANIFEST.MF │ └ spring.factories └ .gitkeep
ここまでの内容を commit します。
ソースコード
ksbysample-library-depend-spring/build.gradle
■その1
dependencies { // dependency-management-plugin によりバージョン番号が自動で設定されるもの // Appendix A. Dependency versions ( http://docs.spring.io/platform/docs/current/reference/htmlsingle/#appendix-dependency-versions ) 参照 compile("org.springframework.boot:spring-boot-autoconfigure") compile("org.springframework.boot:spring-boot-starter-web") compile("org.aspectj:aspectjweaver") testCompile("org.springframework.boot:spring-boot-starter-test") // dependency-management-plugin によりバージョン番号が自動で設定されないもの、あるいは最新バージョンを指定したいもの compile("org.apache.commons:commons-lang3:3.5") compile("com.google.guava:guava:20.0") testCompile("org.assertj:assertj-core:3.6.1") }
- 以下の記述を追加します。
- あとでテストも書くので AssertJ も追加しておきます。
■その2
dependencyManagement { imports { mavenBom 'io.spring.platform:platform-bom:2.0.5.RELEASE' } } bootRepackage { enabled = false } dependencies { .......... }
bootRepackage { enabled = false }
を追加します。
RequestAndResponseLogger.java
package ksbysample.library.dependspring.intercepter; import com.google.common.collect.Iterators; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Arrays; import java.util.Map; import java.util.stream.StreamSupport; public class RequestAndResponseLogger implements MethodInterceptor { private final Logger logger = LoggerFactory.getLogger(this.getClass()); private static final String LOG_REQUEST_INFO = "[req][info ] "; private static final String LOG_REQUEST_HEADER = "[req][header] "; private static final String LOG_REQUEST_COOKIE = "[req][cookie] "; private static final String LOG_REQUEST_PARAMETER = "[req][param ] "; private static final String LOG_RESPONSE_INFO = "[res][info ] "; private static final String LOG_RESPONSE_HEADER = "[res][header] "; @Override public Object invoke(MethodInvocation invocation) throws Throwable { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); loggingRequest(request); Object ret = invocation.proceed(); HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); loggingResponse(response); return ret; } private void loggingRequest(HttpServletRequest request) { loggingRequestInfo(request); loggingRequestHeaders(request); loggingRequestCookies(request); loggingRequestParameters(request); } ..........
RequestAndResponseLoggerAutoConfiguration.java
package ksbysample.library.dependspring.config; import ksbysample.library.dependspring.intercepter.RequestAndResponseLogger; import org.apache.commons.lang3.StringUtils; import org.springframework.aop.Advisor; import org.springframework.aop.aspectj.AspectJExpressionPointcut; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RequestAndResponseLoggerAutoConfiguration { private static final String REQUESTMAPPING_EXPRESSION = "@annotation(org.springframework.web.bind.annotation.RequestMapping)"; @Value("${ksbysample.library.request-and-response-logger.execution:}") private String execution; @Bean @ConditionalOnWebApplication public Advisor requestAndResponseLoggerAdvisor() { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); String expression = StringUtils.EMPTY; if (StringUtils.isNotBlank(this.execution)) { expression = this.execution + " && "; } expression += REQUESTMAPPING_EXPRESSION; pointcut.setExpression(expression); return new DefaultPointcutAdvisor(pointcut, new RequestAndResponseLogger()); } }
- デフォルトでは @RequestMapping アノテーションが付与された全てのメソッドに RequestAndResponseLogger の invoke メソッドの処理を追加します。
- ただし適用するパッケージを制限できるよう application.properties に
ksbysample.library.request-and-response-logger.execution=execution(* ksbysample.webapp.lending.web..*.*(..))
のように設定を追加すれば反映されるようにします。
META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ ksbysample.library.dependspring.config.RequestAndResponseLoggerAutoConfiguration
履歴
2016/12/25
初版発行。