diff --git a/README-CN.md b/README-CN.md index 6502a14..5185405 100644 --- a/README-CN.md +++ b/README-CN.md @@ -5,7 +5,7 @@ |Lib|surgeon-plugin|surgeon-compile| |:---:|:---|:---| -|最新版本|1.0.1|1.0.0| +|最新版本|1.0.2|1.0.1| Surgeon是Android上一个简单,灵活,高性能的方法热替换框架。 @@ -18,7 +18,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.tangxiaolv.surgeon:surgeon-plugin:1.0.1'//version参照上表 + classpath 'com.tangxiaolv.surgeon:surgeon-plugin:1.0.2'//version参照上表 } } @@ -31,7 +31,7 @@ apply plugin: 'com.tangxiaolv.surgeon' //添加注解解析器 dependencies { - annotationProcessor 'com.tangxiaolv.surgeon:surgeon-compile:1.0.0'//version参照上表 + annotationProcessor 'com.tangxiaolv.surgeon:surgeon-compile:1.0.1'//version参照上表 } ``` @@ -41,7 +41,10 @@ dependencies { ```java package com.tangxiaolv.sdk; public class SDKActivity extends AppCompatActivity { - @ReplaceAble + //namespace 命名空间,通常为packageName + className,也可以自定义 + //function 方法名称,通常为当前的方法名字,也可自定义 + //namespace + function必须唯一,否则无法正确被替换 + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") private String getTwo() { return "TWO"; } @@ -52,12 +55,15 @@ public class SDKActivity extends AppCompatActivity { ```java //创建新类实现ISurgeon public class HotReplace implements ISurgeon { - /** - * ref为目标方法的packageName+className+methodName - * @param target 默认传递:目标方法所在对象,如果目标方法为静态,target为null - */ - @Replace(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo") - public String getTwo(Object target) { + + //当前类是否为单例 + @Override + public boolean singleton() { + return false; + } + + @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") + public String getTwo(TargetHandle handle) { return "getTwo from HotReplace2"; } } @@ -69,17 +75,22 @@ public class HotReplace implements ISurgeon { ```java package com.tangxiaolv.sdk; public class SDKActivity extends AppCompatActivity { - @ReplaceAble + + @Override + public boolean singleton() { + return false; + } + + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") private String getTwo() { return "TWO"; } - - @ReplaceAble(extra = "text") + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo.text") private String getTwo(String text) { return text; } - @ReplaceAble(extra = "text") + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getThree") private String getThree(String text) { return "getThree_"+text; } @@ -89,29 +100,40 @@ public class SDKActivity extends AppCompatActivity { **一:静态替换** ```java public class HotReplace implements ISurgeon { + + @Override + public boolean singleton() { + return false; + } + //调用目标方法前调用 - @ReplaceBefore(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo") + //target 目标方法所在对象 + @ReplaceBefore(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public void getTwoBefore(Object target) { } //替换目标方法 - @Replace(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo") + //handle 目标方法的处理类,可通过它调用目标方法和获取目标方法所在对象 + @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public String getTwo(TargetHandle handle) { return "getTwo from remote"; } //目标重载方法替换 - @Replace(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo",extra = "text") + //handle 目标方法的处理类,可通过它调用目标方法和获取目标方法所在对象 + @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo.text") public String getTwo(TargetHandle handle,String text/**目标方法参数*/) { return "getTwo from remote"; } //目标方法调用之后调用 - @ReplaceAfter(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo") + //target 目标方法所在对象 + @ReplaceAfter(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public void getTwoAfter(Object target) { } - @Replace(ref = "com.tangxiaolv.sdk.SDKActivity.getThree", extra = "text") + //替换目标方法 + @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getThree") public String getThree(TargetHandle handle, String text) throws Throwable { String newText = text + "_hack!"; //使用新参数调用原始方法 diff --git a/README.md b/README.md index 2c3cad5..7e511bb 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ English | [中文](https://github.com/TangXiaoLv/Surgeon/blob/master/README-CN.m |Lib|surgeon-plugin|surgeon-compile| |:---:|:---|:---| -|latest|1.0.1|1.0.0| +|latest|1.0.2|1.0.1| Surgeon is a hot function replace framework for Android which was simple to use,flexible,high-performance. @@ -18,7 +18,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.tangxiaolv.surgeon:surgeon-plugin:1.0.1' + classpath 'com.tangxiaolv.surgeon:surgeon-plugin:1.0.2' } } @@ -33,7 +33,7 @@ apply plugin: 'com.tangxiaolv.surgeon' //add annotationProcessor dependencies { - annotationProcessor 'com.tangxiaolv.surgeon:surgeon-compile:1.0.0' + annotationProcessor 'com.tangxiaolv.surgeon:surgeon-compile:1.0.1' } ``` @@ -43,7 +43,10 @@ Getting Started ```java package com.tangxiaolv.sdk; public class SDKActivity extends AppCompatActivity { - @ReplaceAble + //namespace usually is packageName + className,Also can define any string if you want. + //function function name,usually is current function name,Also can define any string if you want. + //namespace + function must unique + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") private String getTwo() { return "TWO"; } @@ -54,12 +57,14 @@ public class SDKActivity extends AppCompatActivity { ```java //Create ISurgeon subclass. public class HotReplace implements ISurgeon { - /** - * ref = target(packageName + className + methodName) - * @param target Defualt passed,The target function owner object,If target function is static then it equal null. - */ - @Replace(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo") - public String getTwo(Object target) { + + @Override + public boolean singleton() { + return false; + } + + @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") + public String getTwo(TargetHandle handle) { return "getTwo from HotReplace2"; } } @@ -71,17 +76,21 @@ Advance ```java package com.tangxiaolv.sdk; public class SDKActivity extends AppCompatActivity { - @ReplaceAble + @Override + public boolean singleton() { + return false; + } + + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") private String getTwo() { return "TWO"; } - - @ReplaceAble(extra = "text") + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo.text") private String getTwo(String text) { return text; } - @ReplaceAble(extra = "text") + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getThree") private String getThree(String text) { return "getThree_"+text; } @@ -91,29 +100,39 @@ public class SDKActivity extends AppCompatActivity { **1.Static Replace** ```java public class HotReplace implements ISurgeon { + @Override + public boolean singleton() { + return false; + } + //called before target function call - @ReplaceBefore(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo") + //target : target function owner object + @ReplaceBefore(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public void getTwoBefore(Object target) { } //replace target function - @Replace(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo") + //handle :You can invoke target function or get target function owner by handler. + @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public String getTwo(TargetHandle handle) { return "getTwo from remote"; } //replace target override function - @Replace(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo",extra = "text") - public String getTwo(TargetHandle handle,String text/**origin params*/) { + //handle :You can invoke target function or get target function owner by handler. + @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo.text") + public String getTwo(TargetHandle handle,String text/**目标方法参数*/) { return "getTwo from remote"; } //called after target function call - @ReplaceAfter(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo") + //target : target function owner object + @ReplaceAfter(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public void getTwoAfter(Object target) { } - @Replace(ref = "com.tangxiaolv.sdk.SDKActivity.getThree", extra = "text") + //replace target function + @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getThree") public String getThree(TargetHandle handle, String text) throws Throwable { String newText = text + "_hack!"; //invoke origin method with new params diff --git a/build.gradle b/build.gradle index 9431cb8..018ce36 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:2.3.0' - classpath 'com.tangxiaolv.surgeon:surgeon-plugin:1.0.1' + classpath 'com.tangxiaolv.surgeon:surgeon-plugin:1.0.2' //jcenter push plugin classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.4' diff --git a/example/sdk/build.gradle b/example/sdk/build.gradle index 4e6c3a7..366edc2 100644 --- a/example/sdk/build.gradle +++ b/example/sdk/build.gradle @@ -29,4 +29,5 @@ dependencies { }) compile 'com.android.support:appcompat-v7:25.3.1' testCompile 'junit:junit:4.12' + //compile project(':surgeon-core') } \ No newline at end of file diff --git a/example/sdk/src/main/java/com/tangxiaolv/sdk/MyLinearLayout.java b/example/sdk/src/main/java/com/tangxiaolv/sdk/MyLinearLayout.java index 0bedf49..94b9e24 100644 --- a/example/sdk/src/main/java/com/tangxiaolv/sdk/MyLinearLayout.java +++ b/example/sdk/src/main/java/com/tangxiaolv/sdk/MyLinearLayout.java @@ -2,11 +2,11 @@ import android.content.Context; import android.graphics.Canvas; -import android.text.Layout; import android.util.AttributeSet; -import android.view.View; import android.widget.LinearLayout; +import com.surgeon.weaving.annotations.ReplaceAble; + public class MyLinearLayout extends LinearLayout { public MyLinearLayout(Context context) { super(context); @@ -20,6 +20,7 @@ public MyLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } + @ReplaceAble(namespace = "com.tangxiaolv.sdk.MyLinearLayout", function = "onMeasure") @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); diff --git a/example/sdk/src/main/java/com/tangxiaolv/sdk/SDKActivity.java b/example/sdk/src/main/java/com/tangxiaolv/sdk/SDKActivity.java index 708c284..295d00f 100644 --- a/example/sdk/src/main/java/com/tangxiaolv/sdk/SDKActivity.java +++ b/example/sdk/src/main/java/com/tangxiaolv/sdk/SDKActivity.java @@ -47,7 +47,7 @@ public void after(Object[] params) { }); } - @ReplaceAble + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "oneClick") public void oneClick(View view) { content.setText(getOne()); } @@ -61,22 +61,22 @@ public void threeClick(View view) { content.setText(getThree("Text")); } - @ReplaceAble + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getOne") private String getOne() { return "ONE"; } - @ReplaceAble + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") private final static String getTwo() { return "TWO"; } - @ReplaceAble(extra = "text") + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo.text") private String getTwo(String text) { return text; } - @ReplaceAble(extra = "text") + @ReplaceAble(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getThree.text") private String getThree(String text) { return "getThree_" + text; } diff --git a/example/sdk/src/main/java/com/tangxiaolv/sdk/StringUtils.java b/example/sdk/src/main/java/com/tangxiaolv/sdk/StringUtils.java index b4bc435..0490135 100644 --- a/example/sdk/src/main/java/com/tangxiaolv/sdk/StringUtils.java +++ b/example/sdk/src/main/java/com/tangxiaolv/sdk/StringUtils.java @@ -4,7 +4,7 @@ public class StringUtils { - @ReplaceAble + @ReplaceAble(namespace = "com.tangxiaolv.sdk.StringUtils", function = "getThree") public static String getThree() { return "THREE"; } diff --git a/example/simple/build.gradle b/example/simple/build.gradle index ce5e0df..30d12a3 100644 --- a/example/simple/build.gradle +++ b/example/simple/build.gradle @@ -29,6 +29,7 @@ dependencies { testCompile 'junit:junit:4.12' compile project(':example:sdk') + annotationProcessor 'com.tangxiaolv.surgeon:surgeon-compile:1.0.1' + //annotationProcessor project(':surgeon-compile') //compile project(':surgeon-core') - annotationProcessor project(':surgeon-compile') } \ No newline at end of file diff --git a/example/simple/src/main/java/com/tangxiaolv/surgeon/HotReplace.java b/example/simple/src/main/java/com/tangxiaolv/surgeon/HotReplace.java index a5ed178..a3c70fc 100644 --- a/example/simple/src/main/java/com/tangxiaolv/surgeon/HotReplace.java +++ b/example/simple/src/main/java/com/tangxiaolv/surgeon/HotReplace.java @@ -15,8 +15,22 @@ public class HotReplace implements ISurgeon { * @param handle {@link TargetHandle} * @param view origin params */ - @Replace(ref = "com.tangxiaolv.sdk.SDKActivity.oneClick") + @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "oneClick") public void showToast(TargetHandle handle, View view) { Toast.makeText(view.getContext(), "Hack!!!", Toast.LENGTH_SHORT).show(); } + + @Replace(namespace = "com.tangxiaolv.sdk.MyLinearLayout", function = "onMeasure") + public void onMeasure(TargetHandle handle, int widthMeasureSpec, int heightMeasureSpec) throws Throwable { + int w_s = View.MeasureSpec.getSize(widthMeasureSpec); + int w_m = View.MeasureSpec.getMode(widthMeasureSpec); + int h_s = View.MeasureSpec.getSize(heightMeasureSpec); + int h_m = View.MeasureSpec.getMode(heightMeasureSpec); + handle.proceed(View.MeasureSpec.makeMeasureSpec(w_s / 2, w_m), heightMeasureSpec); + } + + @Override + public boolean singleton() { + return true; + } } diff --git a/example/simple/src/main/java/com/tangxiaolv/surgeon/HotReplace2.java b/example/simple/src/main/java/com/tangxiaolv/surgeon/HotReplace2.java index 564ad2e..a8f12fe 100644 --- a/example/simple/src/main/java/com/tangxiaolv/surgeon/HotReplace2.java +++ b/example/simple/src/main/java/com/tangxiaolv/surgeon/HotReplace2.java @@ -8,8 +8,6 @@ import com.surgeon.weaving.core.TargetHandle; import com.surgeon.weaving.core.interfaces.ISurgeon; -import static android.content.ContentValues.TAG; - public class HotReplace2 implements ISurgeon { private final static String TAG = "HotReplace2"; @@ -19,7 +17,7 @@ public class HotReplace2 implements ISurgeon { * * @param target The function owner's object. */ - @ReplaceBefore(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo") + @ReplaceBefore(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public void getTwoBefore(Object target) { Log.d(TAG, "getTwoBefore"); } @@ -30,7 +28,7 @@ public void getTwoBefore(Object target) { * @param handle The function owner's object. * @return new result */ - @Replace(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo") + @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public String getTwo(TargetHandle handle) { return "getTwo from HotReplace2"; } @@ -42,7 +40,7 @@ public String getTwo(TargetHandle handle) { * @param text origin params * @return new result */ - @Replace(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo", extra = "text") + @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo.text") public String getTwo(TargetHandle handle, String text/**origin params*/) { return "getTwo from remote"; } @@ -52,7 +50,7 @@ public String getTwo(TargetHandle handle, String text/**origin params*/) { * * @param target The function owner's object. */ - @ReplaceAfter(ref = "com.tangxiaolv.sdk.SDKActivity.getTwo") + @ReplaceAfter(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getTwo") public void getTwoAfter(Object target) { Log.d(TAG, "getTwoAfter"); } @@ -64,10 +62,15 @@ public void getTwoAfter(Object target) { * @param text origin params * @return new result */ - @Replace(ref = "com.tangxiaolv.sdk.SDKActivity.getThree", extra = "text") + @Replace(namespace = "com.tangxiaolv.sdk.SDKActivity", function = "getThree.text") public String getThree(TargetHandle handle, String text) throws Throwable { String newText = text + "_hack!"; - //invoke origin method with new params + //invoke origin function with new params return (String) handle.proceed(newText); } + + @Override + public boolean singleton() { + return false; + } } diff --git a/surgeon-annotations/gradle.properties b/surgeon-annotations/gradle.properties index b732fd6..5553fc9 100644 --- a/surgeon-annotations/gradle.properties +++ b/surgeon-annotations/gradle.properties @@ -4,7 +4,7 @@ GROUP_ID=com.tangxiaolv.surgeon #must be the same as MODULE name ARTIFACT_ID=surgeon-annotations #publicVersion -PUBLIC_VERSION=1.0.0 +PUBLIC_VERSION=1.0.1 #jcenter repo library Name LIBRARY_NAME=surgeon-annotations #library description diff --git a/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/Replace.java b/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/Replace.java index 2502efe..5bc6a7a 100644 --- a/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/Replace.java +++ b/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/Replace.java @@ -7,19 +7,18 @@ import static java.lang.annotation.RetentionPolicy.CLASS; /** - * Replace new method when target method called. + * Replace new function when target function called. */ @Retention(CLASS) @Target({METHOD}) public @interface Replace { - /** - * The target method reference + * The target function namespace. */ - String ref(); + String namespace(); /** - * Extra mark,Usually used in override. + * Function name */ - String extra() default ""; + String function(); } diff --git a/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/ReplaceAble.java b/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/ReplaceAble.java index ed01e79..c1920c5 100644 --- a/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/ReplaceAble.java +++ b/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/ReplaceAble.java @@ -7,13 +7,18 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Used in AspectJ(AOP Framework for Java).It's meaning is what method should be weaving. + * Used in AspectJ(AOP Framework for Java).It's meaning is what function should be weaving. */ @Retention(RUNTIME) @Target({METHOD}) public @interface ReplaceAble { /** - * Extra mark,Usually used in override. + * The namespace of target function. */ - String extra() default ""; + String namespace(); + + /** + * Function name + */ + String function(); } diff --git a/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/ReplaceAfter.java b/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/ReplaceAfter.java index 353c307..14cfa6c 100644 --- a/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/ReplaceAfter.java +++ b/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/ReplaceAfter.java @@ -7,18 +7,18 @@ import static java.lang.annotation.RetentionPolicy.CLASS; /** - * Called after when target method called. + * Called after when target function called. */ @Retention(CLASS) @Target({METHOD}) public @interface ReplaceAfter { /** - * The target method reference + * The namespace of target function. */ - String ref(); + String namespace(); /** - * Extra mark,Usually used in override. + * Function name */ - String extra() default ""; + String function(); } diff --git a/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/ReplaceBefore.java b/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/ReplaceBefore.java index 039bb7a..4f8f1d3 100644 --- a/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/ReplaceBefore.java +++ b/surgeon-annotations/src/main/java/com/surgeon/weaving/annotations/ReplaceBefore.java @@ -7,18 +7,18 @@ import static java.lang.annotation.RetentionPolicy.CLASS; /** - * Called before target method called. + * Called before target function called. */ @Retention(CLASS) @Target({METHOD}) public @interface ReplaceBefore { /** - * The target method reference + * The namespace of target function. */ - String ref(); + String namespace(); /** - * Extra mark,Usually used in override. + * Function name */ - String extra() default ""; + String function(); } diff --git a/surgeon-compile/gradle.properties b/surgeon-compile/gradle.properties index 36ee902..cd9982c 100644 --- a/surgeon-compile/gradle.properties +++ b/surgeon-compile/gradle.properties @@ -4,7 +4,7 @@ GROUP_ID=com.tangxiaolv.surgeon #must be the same as MODULE name ARTIFACT_ID=surgeon-compile #publicVersion -PUBLIC_VERSION=1.0.0 +PUBLIC_VERSION=1.0.1 #jcenter repo library Name LIBRARY_NAME=surgeon-compile #library description diff --git a/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/Replace.java b/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/Replace.java index 2502efe..5bc6a7a 100644 --- a/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/Replace.java +++ b/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/Replace.java @@ -7,19 +7,18 @@ import static java.lang.annotation.RetentionPolicy.CLASS; /** - * Replace new method when target method called. + * Replace new function when target function called. */ @Retention(CLASS) @Target({METHOD}) public @interface Replace { - /** - * The target method reference + * The target function namespace. */ - String ref(); + String namespace(); /** - * Extra mark,Usually used in override. + * Function name */ - String extra() default ""; + String function(); } diff --git a/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/ReplaceAble.java b/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/ReplaceAble.java index ed01e79..c1920c5 100644 --- a/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/ReplaceAble.java +++ b/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/ReplaceAble.java @@ -7,13 +7,18 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** - * Used in AspectJ(AOP Framework for Java).It's meaning is what method should be weaving. + * Used in AspectJ(AOP Framework for Java).It's meaning is what function should be weaving. */ @Retention(RUNTIME) @Target({METHOD}) public @interface ReplaceAble { /** - * Extra mark,Usually used in override. + * The namespace of target function. */ - String extra() default ""; + String namespace(); + + /** + * Function name + */ + String function(); } diff --git a/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/ReplaceAfter.java b/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/ReplaceAfter.java index 353c307..14cfa6c 100644 --- a/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/ReplaceAfter.java +++ b/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/ReplaceAfter.java @@ -7,18 +7,18 @@ import static java.lang.annotation.RetentionPolicy.CLASS; /** - * Called after when target method called. + * Called after when target function called. */ @Retention(CLASS) @Target({METHOD}) public @interface ReplaceAfter { /** - * The target method reference + * The namespace of target function. */ - String ref(); + String namespace(); /** - * Extra mark,Usually used in override. + * Function name */ - String extra() default ""; + String function(); } diff --git a/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/ReplaceBefore.java b/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/ReplaceBefore.java index 039bb7a..4f8f1d3 100644 --- a/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/ReplaceBefore.java +++ b/surgeon-compile/src/main/java/com/surgeon/weaving/annotations/ReplaceBefore.java @@ -7,18 +7,18 @@ import static java.lang.annotation.RetentionPolicy.CLASS; /** - * Called before target method called. + * Called before target function called. */ @Retention(CLASS) @Target({METHOD}) public @interface ReplaceBefore { /** - * The target method reference + * The namespace of target function. */ - String ref(); + String namespace(); /** - * Extra mark,Usually used in override. + * Function name */ - String extra() default ""; + String function(); } diff --git a/surgeon-compile/src/main/java/com/surgeon/weaving/compile/SurgeonProcessor.java b/surgeon-compile/src/main/java/com/surgeon/weaving/compile/SurgeonProcessor.java index 66e1e80..e7d2b16 100644 --- a/surgeon-compile/src/main/java/com/surgeon/weaving/compile/SurgeonProcessor.java +++ b/surgeon-compile/src/main/java/com/surgeon/weaving/compile/SurgeonProcessor.java @@ -120,7 +120,7 @@ private List findAndParseTargets(RoundEnvironment env) { continue; } Replace replace = e.getAnnotation(Replace.class); - parseReplace(e, group, "", replace.ref(), replace.extra()); + parseReplace(e, group, "", replace.namespace(), replace.function()); } // Process each @ReplaceBefore element. @@ -129,7 +129,7 @@ private List findAndParseTargets(RoundEnvironment env) { continue; } ReplaceBefore replace = e.getAnnotation(ReplaceBefore.class); - parseReplace(e, group, "before_", replace.ref(), replace.extra()); + parseReplace(e, group, "before_", replace.namespace(), replace.function()); } // Process each @ReplaceAfter element. @@ -138,7 +138,7 @@ private List findAndParseTargets(RoundEnvironment env) { continue; } ReplaceAfter replace = e.getAnnotation(ReplaceAfter.class); - parseReplace(e, group, "after_", replace.ref(), replace.extra()); + parseReplace(e, group, "after_", replace.namespace(), replace.function()); } generateMasterJavaFile(group, javaFiles); @@ -149,18 +149,18 @@ private void parseReplace( Element e, Map> group, String prefix, - String ref, - String extra) { - int lastPointIndex = ref.lastIndexOf("."); - String namespace = ref.substring(0, lastPointIndex); - String methodName = ref.substring(lastPointIndex + 1, ref.length()); - String fullName = prefix + methodName + (extra.length() == 0 ? "" : "." + extra); + String namespace, + String function) { + if (isEmpty(namespace) || isEmpty(function)) { + error("namespace=%s or function=%s can't be empty.", namespace, function); + } + String fullName = prefix + function; Map collect; if (group.containsKey(namespace)) { collect = group.get(namespace); if (collect.containsKey(fullName)) { - error("duplicate define %s.%s", ref, extra); + error("duplicate define %s.%s", namespace, function); } } else { collect = new HashMap<>(); diff --git a/surgeon-core/build.gradle b/surgeon-core/build.gradle index d2d3106..65f0f44 100644 --- a/surgeon-core/build.gradle +++ b/surgeon-core/build.gradle @@ -31,8 +31,7 @@ dependencies { }) testCompile 'junit:junit:4.12' compile 'org.aspectj:aspectjrt:1.8.10' - compile 'com.tangxiaolv.surgeon:surgeon-annotations:1.0.0' - //compile project(':surgeon-annotations') + compile 'com.tangxiaolv.surgeon:surgeon-annotations:1.0.1' } android.libraryVariants.all { variant -> diff --git a/surgeon-core/gradle.properties b/surgeon-core/gradle.properties index 821dc8a..185410d 100644 --- a/surgeon-core/gradle.properties +++ b/surgeon-core/gradle.properties @@ -4,7 +4,7 @@ GROUP_ID=com.tangxiaolv.surgeon #must be the same as MODULE name ARTIFACT_ID=surgeon-core #publicVersion -PUBLIC_VERSION=1.0.1 +PUBLIC_VERSION=1.0.2 #jcenter repo library Name LIBRARY_NAME=surgeon-core #library description diff --git a/surgeon-core/src/main/java/com/surgeon/weaving/core/InnerCache.java b/surgeon-core/src/main/java/com/surgeon/weaving/core/InnerCache.java index ef34dd8..016ee5d 100644 --- a/surgeon-core/src/main/java/com/surgeon/weaving/core/InnerCache.java +++ b/surgeon-core/src/main/java/com/surgeon/weaving/core/InnerCache.java @@ -11,7 +11,7 @@ class InnerCache { private final LruCache masterCache = new LruCache<>(20); - private final LruCache ownerCache = new LruCache<>(20); + private final Map ownerCache = new HashMap<>(); private final Map replaceWapperCache = new HashMap<>(); private static class Lazy { diff --git a/surgeon-core/src/main/java/com/surgeon/weaving/core/MasterFinder.java b/surgeon-core/src/main/java/com/surgeon/weaving/core/MasterFinder.java index 96eaec9..e388930 100644 --- a/surgeon-core/src/main/java/com/surgeon/weaving/core/MasterFinder.java +++ b/surgeon-core/src/main/java/com/surgeon/weaving/core/MasterFinder.java @@ -1,6 +1,5 @@ package com.surgeon.weaving.core; -import com.surgeon.weaving.annotations.ReplaceAble; import com.surgeon.weaving.core.exceptions.SurgeonException; import com.surgeon.weaving.core.interfaces.Continue; import com.surgeon.weaving.core.interfaces.IMaster; @@ -14,7 +13,7 @@ import static com.surgeon.weaving.core.ASPConstant.BEFORE; /** - * The master {@link ReplaceAbleAspect},Used for find replace method. + * The master {@link ReplaceAbleAspect},Used for find replace function. */ class MasterFinder { @@ -32,22 +31,22 @@ static MasterFinder getInstance() { } /** - * Create {@link IMaster} and find replace method. + * Create {@link IMaster} and find replace function. * - * @param namespace The key of master.eg:PackageName + ClassName + * @param namespace The namespace of function * @param prefix {@link ASPConstant#BEFORE},{@link ASPConstant#EMPTY}, {@link * ASPConstant#AFTER} - * @param fullName The key of method.eg:MethodName + {@link ReplaceAble#extra()} - * @param target original instance + * @param function The name of function. + * @param target Original instance or {@link TargetHandle} * @param args Input params * @return new result */ Object findAndInvoke(String namespace, String prefix, - String fullName, + String function, Object target, Object[] args) throws SurgeonException { - if (isEmpty(namespace) || isEmpty(fullName)) return Continue.class; + if (isEmpty(namespace) || isEmpty(function)) return Continue.class; try { String masterPath = PREFIX + namespace.replace(".", "_"); IMaster master = InnerCache.getInstance().getMaster(masterPath); @@ -64,7 +63,7 @@ Object findAndInvoke(String namespace, //runtime repalce Object wrapper; - String runtimeKey = namespace + "." + fullName; + String runtimeKey = namespace + "." + function; if (AFTER.equals(prefix)) { wrapper = InnerCache.getInstance().popReplaceWapper(runtimeKey); } else { @@ -87,9 +86,9 @@ Object findAndInvoke(String namespace, } //static repalce - SurgeonMethod newMethod = master.find(prefix + fullName); - if (newMethod != null) { - return invoke(newMethod, copyOfArgs); + SurgeonMethod replaceMethod = master.find(prefix + function); + if (replaceMethod != null) { + return invoke(replaceMethod, copyOfArgs); } } catch (ClassNotFoundException ignored) { //ignored @@ -108,13 +107,13 @@ private Object invoke(SurgeonMethod method, Object[] args) if (ownerInstance == null) { Class clazz = method.getOwner(); ownerInstance = clazz.newInstance(); - InnerCache.getInstance().putMethodOwner(method.getOwner(), ownerInstance); + if (ownerInstance instanceof ISurgeon && ((ISurgeon) ownerInstance).singleton()) { + InnerCache.getInstance().putMethodOwner(method.getOwner(), ownerInstance); + } } - if (ownerInstance instanceof ISurgeon) { return method.getNewMethod().invoke(ownerInstance, args); } - return Continue.class; } } diff --git a/surgeon-core/src/main/java/com/surgeon/weaving/core/ReplaceAbleAspect.java b/surgeon-core/src/main/java/com/surgeon/weaving/core/ReplaceAbleAspect.java index 6c8aeac..cca2c66 100644 --- a/surgeon-core/src/main/java/com/surgeon/weaving/core/ReplaceAbleAspect.java +++ b/surgeon-core/src/main/java/com/surgeon/weaving/core/ReplaceAbleAspect.java @@ -11,8 +11,6 @@ import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; -import java.util.HashMap; - import static com.surgeon.weaving.core.ASPConstant.AFTER; import static com.surgeon.weaving.core.ASPConstant.BEFORE; import static com.surgeon.weaving.core.ASPConstant.EMPTY; @@ -33,7 +31,7 @@ public void withinAnnotatedClass() { public void methodInsideAnnotatedType() { } - //any method with ReplaceAble + //any function with ReplaceAble @Pointcut("execution(@com.surgeon.weaving.annotations.ReplaceAble * *(..)) || methodInsideAnnotatedType()") public void method() { } @@ -42,12 +40,12 @@ public void method() { public Object replacedIfNeeded(ProceedingJoinPoint jPoint) throws Throwable { String[] pair = parseNamespaceAndMethodName(jPoint); String namespace = pair[0]; - String fullName = pair[1]; + String function = pair[1]; - //invoke before method - MasterFinder.getInstance().findAndInvoke(namespace, BEFORE, fullName, jPoint.getThis(), jPoint.getArgs()); - //invoke method - Object result = MasterFinder.getInstance().findAndInvoke(namespace, EMPTY, fullName, + //invoke before function + MasterFinder.getInstance().findAndInvoke(namespace, BEFORE, function, jPoint.getThis(), jPoint.getArgs()); + //invoke function + Object result = MasterFinder.getInstance().findAndInvoke(namespace, EMPTY, function, new TargetHandle(jPoint), jPoint.getArgs()); return result != Continue.class ? result : jPoint.proceed(); } @@ -56,19 +54,17 @@ public Object replacedIfNeeded(ProceedingJoinPoint jPoint) throws Throwable { public void afterIfNeeded(JoinPoint jPoint) throws Throwable { String[] pair = parseNamespaceAndMethodName(jPoint); String namespace = pair[0]; - String fullName = pair[1]; + String function = pair[1]; - //invoke after method - MasterFinder.getInstance().findAndInvoke(namespace, AFTER, fullName, jPoint.getThis(), jPoint.getArgs()); + //invoke after function + MasterFinder.getInstance().findAndInvoke(namespace, AFTER, function, jPoint.getThis(), jPoint.getArgs()); } private String[] parseNamespaceAndMethodName(JoinPoint jPoint) { MethodSignature signature = (MethodSignature) jPoint.getSignature(); - String namespace = signature.getDeclaringTypeName(); - String methodName = signature.getName(); ReplaceAble replaceAble = signature.getMethod().getAnnotation(ReplaceAble.class); - String extra = replaceAble.extra(); - String fullName = methodName + (extra.length() == 0 ? "" : "." + extra); - return new String[]{namespace, fullName}; + String namespace = replaceAble.namespace(); + String function = replaceAble.function(); + return new String[]{namespace, function}; } } diff --git a/surgeon-core/src/main/java/com/surgeon/weaving/core/Surgeon.java b/surgeon-core/src/main/java/com/surgeon/weaving/core/Surgeon.java index c60ca14..469b810 100644 --- a/surgeon-core/src/main/java/com/surgeon/weaving/core/Surgeon.java +++ b/surgeon-core/src/main/java/com/surgeon/weaving/core/Surgeon.java @@ -5,9 +5,9 @@ public class Surgeon { /** - * Runtime to replace original method's result. + * Runtime to replace original function's result. * - * @param ref The original method reference. + * @param ref namespace + "." + function * @param result New result. */ public static void replace(String ref, Object result) { @@ -15,10 +15,10 @@ public static void replace(String ref, Object result) { } /** - * Runtime to replace original method. + * Runtime to replace original function. * - * @param ref The original method reference. - * @param replacer New method. + * @param ref namespace + "." + function + * @param replacer new function. */ public static void replace(String ref, Replacer replacer) { InnerCache.getInstance().addReplaceWapper(ref, new ReplaceWapper(replacer, replacer != null)); diff --git a/surgeon-core/src/main/java/com/surgeon/weaving/core/SurgeonMethod.java b/surgeon-core/src/main/java/com/surgeon/weaving/core/SurgeonMethod.java index c92346b..7ec699b 100644 --- a/surgeon-core/src/main/java/com/surgeon/weaving/core/SurgeonMethod.java +++ b/surgeon-core/src/main/java/com/surgeon/weaving/core/SurgeonMethod.java @@ -4,7 +4,7 @@ import java.lang.reflect.Method; /** - * The replace method wrapper. + * The replace function wrapper. */ public class SurgeonMethod { private Class owner; diff --git a/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/Continue.java b/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/Continue.java index 5aaff54..69bf2dc 100644 --- a/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/Continue.java +++ b/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/Continue.java @@ -1,7 +1,7 @@ package com.surgeon.weaving.core.interfaces; /** - * If MasterFinder#findAndInvoke return Continue.class,Then continue to call original method. + * If MasterFinder#findAndInvoke return Continue.class,Then continue to call original function. */ public interface Continue { } diff --git a/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/IMaster.java b/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/IMaster.java index 2699e67..9698f7f 100644 --- a/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/IMaster.java +++ b/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/IMaster.java @@ -3,11 +3,11 @@ import com.surgeon.weaving.core.SurgeonMethod; /** - * The replace manager for the same namespace.The implements generated by AnnotationProcesscor. + * The replace manager for the same namespace.The subclass generated by AnnotationProcesscor. */ public interface IMaster { /** - * @param name The key of SurgeonMethod + * @param function The key of SurgeonMethod */ - SurgeonMethod find(String name); + SurgeonMethod find(String function); } diff --git a/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/ISurgeon.java b/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/ISurgeon.java index db2f1eb..8c7fb4c 100644 --- a/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/ISurgeon.java +++ b/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/ISurgeon.java @@ -1,7 +1,12 @@ package com.surgeon.weaving.core.interfaces; /** - * All replace method owner need implements. + * All replace function owner need to extends. */ public interface ISurgeon { + + /** + * Control current object to singleton. + */ + boolean singleton(); } diff --git a/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/Replacer.java b/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/Replacer.java index 2cac194..c5a5b89 100644 --- a/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/Replacer.java +++ b/surgeon-core/src/main/java/com/surgeon/weaving/core/interfaces/Replacer.java @@ -1,30 +1,30 @@ package com.surgeon.weaving.core.interfaces; /** - * The callback of original method called. + * The callback of original function called. * * @param The return value of {@link Replacer#replace(Object[])} */ public interface Replacer { /** - * Called before original method called. + * Called before original function called. * - * @param params The original method input params. + * @param params The original function input params. */ void before(Object[] params); /** - * Replace original method. + * Replace original function. * - * @param params The original method input params. + * @param params The original function input params. * @return new return result. */ T replace(Object[] params); /** - * Called after original method called. + * Called after original function called. * - * @param params The original method input params. + * @param params The original function input params. */ void after(Object[] params); } diff --git a/surgeon-plugin/gradle.properties b/surgeon-plugin/gradle.properties index f5f8118..acf9534 100644 --- a/surgeon-plugin/gradle.properties +++ b/surgeon-plugin/gradle.properties @@ -4,7 +4,7 @@ GROUP_ID=com.tangxiaolv.surgeon #must be the same as MODULE name ARTIFACT_ID=surgeon-plugin #publicVersion -PUBLIC_VERSION=1.0.1 +PUBLIC_VERSION=1.0.2 #jcenter repo library Name LIBRARY_NAME=surgeon-plugin #library description diff --git a/surgeon-plugin/src/main/groovy/com/surgeon/weaving/plugin/SurgeonPlugin.groovy b/surgeon-plugin/src/main/groovy/com/surgeon/weaving/plugin/SurgeonPlugin.groovy index 2d33a83..cdde737 100644 --- a/surgeon-plugin/src/main/groovy/com/surgeon/weaving/plugin/SurgeonPlugin.groovy +++ b/surgeon-plugin/src/main/groovy/com/surgeon/weaving/plugin/SurgeonPlugin.groovy @@ -27,7 +27,7 @@ class SurgeonPlugin implements Plugin { project.dependencies { compile 'org.aspectj:aspectjrt:1.8.10' - compile 'com.tangxiaolv.surgeon:surgeon-core:1.0.1' + compile 'com.tangxiaolv.surgeon:surgeon-core:1.0.2' } project.extensions.create('surgeon', SurgeonExtension)