Mybatis 인터셉터 직관에 대해 잘 모르는 많은 Java 초보자가 있습니다. 여기서는 Java의 Mybatis 인터셉터 직관을 설명하기 위해 다음 기사를 구성 할 것입니다.
이 기사는 주로 Mybatis의 플러그인 메커니즘을 분석하는데, 이는 실제로 Java Dynamic Proxy의 책임 체인 모델 구현입니다.
공식 문서에 따르면. MyBatis는 인터셉터 주석의 서명 매개 변수를 결정하는 다음 방법 만 인터셉트 할 수 있습니다.
코드는 다음과 같습니다
집행자 (업데이트, 쿼리, 플러시 스테이트, 커밋, 롤백, getTransaction, Close, isclose) 매개 변수 핸들러 (getParameterObject, setParameters) resultShandler (handleresultsets, handleoutpuparameters) stateHandler (준비, 매개 변수화, 배치, 업데이트, 쿼리)
인터셉터 처리의 소스 코드는 다음과 같습니다. 여기서 interceptorchain.pluginall (..)은 사용자 정의 인터셉터 직조입니다.
코드는 다음과 같습니다
/ * org.apache.ibatis.session.configuration class */public parameterhandler newParameterAndler (MappedStatement MappedStatement, object ParameterObject, BoundSQL BoundSQL) {ParameterAndler ParameterHandler = MAPPEDSTATEMENT.GETLANG (). /* intercept parameterAndler*/ ParameterAndler = (ParameterAndler) interceptorchain.pluginall (ParameterAndler); return parameterHandler;} public resultsEtandler newResultSethandler (집행자, 맵핑 스테이트 맵핑 스테이트, 행 바운드로 바운드, 파라미터 핸들러 매개 변수 핸들러, 레이 술란 더 resulthandler, boundsql boundsql) {resultEthandler resultShaultEdThernsultsler (executor, renstatement, mappedstatement, mappedstatement, mappedstatement) BONDSQL, ROWBOUNDS); /* intercept resultesThandler*/ resultSetHandler = (resultSetHandler) interceptorchain.pluginall (resultesThandler); return resultSetHandler;} public statement hewStatementHandler (집행자, 맵핑 스테이트 매핑 스테이트, 객체 매개 변수, 행 바운드, rowbounds rowbounds, resulthandler rigsulthandler, boundsql boundsql) {statehandler stateHandler = 새로운 라우팅 스테이트 핸드 러 (exectingStatementHandler) (매개 변수, 매개 변수, rowbounds, rowbounds, rowbounds, rowbounds. boundsql); /* intercept stateHandler*/ stateHandler = (stateHandler) interceptorchain.pluginall (StateHandler); return stateHandler;} 공개 집행자 NewExecutor (트랜잭션 트랜잭션, executOptype executOptype) {executOple = executOptype == null? defaultexecutortype : executipe; ExecutOple = ExecutOptype == NULL? ExecutOptype.simple : Executipe; 집행자 집행자; if (ExecutOple.batch == ExecutOptype) {executor = new BatchExecutor (this, transaction); } else if (executorType.reuse == executOptype) {executor = new reuseexecutor (this, transaction); } else {executor = new SimpleExexecutor (이, 트랜잭션); } if (Cacheenabled) {Executor = New CachingExecutor (Executor); } /* intercept executor* / executor = (Executor) interceptorchain.pluginall (Executor); 귀환 집행자;} 사용자 정의 인터셉터를 구현하려면 인터셉터 인터페이스 만 구현하면됩니다. 일반 코드는 다음과 같습니다.
코드는 다음과 같습니다
/* intercept*/ @intercepts ({@signature (type = stationhandler.class, method = "repary", args = {connection.class}))를 나타내는 주석의 메소드 및 매개 변수는 공개 클래스 {public object (intercrect invoceation (invocection intercepts) {doSomeather (); / * 참고 : 여기서, invocation.proceation () 메소드는 실제로 인터셉트 토 체인 체인의 트래버스 호출 (즉, 인터셉터의 모든 등록 된 인터셉트 메소드를 실행하기 위해)과 최종 프록시 오브젝트의 원래 메소드 호출 */ return invocation.proceed (); } / * 대상 대상에 대한 프록시를 생성하고 @Intercepts의 주석은 plugin.wrap * / @override public Object Plugin (Object Target)에 사용됩니다. { / * 대상 클래스가 StateHandler 형식의 경우 대상 클래스가 래핑되며 의미없는 프록시가 사용되지 않습니다 * / return (target instanceOf StateHandler)? } /* 사용자 정의 인터셉터 구성 매개 변수를 설정하는 데 사용* / @override public void setProperties (속성 속성) {}} 그중에서도 통화를 가로 채기위한 코드는 plugin.wrap에 있습니다.
코드는 다음과 같습니다
/* org.apache.ibatis.plugin.plugin class*/public class 플러그인은 invocationhandler {/* 코드를 생략합니다 ...*/public static 객체 랩 (객체 대상, 인터셉트 인터셉터) {/* 여기서 interceptor*/map <class <?>의 주석 시그니처를 얻는 것입니다. class <?> type = target.getClass (); /* 대상 클래스와 일치하는 인터페이스를 가져옵니다*/ class <?> [] 인터페이스 = getAllInterfaces (type, signaturemap); if (interfaces.length> 0) { /* JDK Dynamic Proxy* / return proxy.newProxyInstance (type.getClassLoader (), 인터페이스, 새 플러그인 (대상, 인터셉터, SignaturemAp)); } 반환 대상; } /* 인터셉트 대상 클래스의 모든 방법의 실행은 여기에서 실행됩니다* / @override public object invoke (개체 프록시, 메소드 메소드, 오브젝트 [] args) 던질 가능 {try {set <방법> 메소드 = signaturemap.get (method.getDeclaringClass ()); if (methods! = null && methods.contains (method)) { /* 인터셉터 메소드를 실행합니다* / return interceptor.intercept (새 호출 (target, method, args)); } return method.invoke (target, args); } catch (예외 e) {throw exception.unwrapThrowable (e); }} / * 코드 생략 ... * /}Mybatis 인터셉터 설계의 핵심 코드는 비교적 간단하지만 충분히 유연하다는 것을 알 수 있습니다. 실제로 그것을 사용할 때는 무의미한 프록시 (플러그인 .wrap)가되지 않도록주의하십시오.