AspectJ支持编译期和加载时代码注入
Advice(通知):?典型的 Advice 类型有 before、after 和 around,分别表示在目标方法执行之前、执行后和完全替代目标方法执行的代码。
Joint point(连接点):?程序中可能作为代码注入目标的特定的点和入口。
Pointcut(切入点):?告诉代码注入工具,在何处注入一段特定代码的表达式。
Aspect(切面):?Pointcut 和 Advice 的组合看做切面。例如,在本例中通过定义一个 pointcut 和给定恰当的advice,添加一个了内存缓存的切面。
Weaving(织入):?注入代码(advices)到目标位置(joint points)的过程。
AspectJ环境配置:
1.配置gradle
根项目gradle:
classpath 'org.aspectj:aspectjtools:1.8.9'
classpath 'org.aspectj:aspectjweaver:1.8.9'
AsepctJ项目:
api 'org.aspectj:aspectjrt:1.8.13'
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
android.libraryVariants.all { variant ->
JavaCompile javaCompile = variant.javaCompile
javaCompile.doLast {
String[] args = ["-showWeaveInfo",
"-1.5",
"-inpath", javaCompile.destinationDir.toString(),
"-aspectpath", javaCompile.classpath.asPath,
"-d", javaCompile.destinationDir.toString(),
"-classpath", javaCompile.classpath.asPath,
"-bootclasspath", android.bootClasspath.join(
File.pathSeparator)]
MessageHandler handler = new MessageHandler(true)
new Main().run(args, handler)
def log = project.logger
for (IMessage message : handler.getMessages(null, true)) {
switch (message.getKind()) {
case IMessage.ABORT:
case IMessage.ERROR:
case IMessage.FAIL:
log.error message.message, message.thrown
break
case IMessage.WARNING:
case IMessage.INFO:
log.info message.message, message.thrown
break
case IMessage.DEBUG:
log.debug message.message, message.thrown
break
}
}
}
}
如果直接在app的gradle中配置
implementation 'org.aspectj:aspectjrt:1.8.13'
import org.aspectj.bridge.IMessage
import org.aspectj.bridge.MessageHandler
import org.aspectj.tools.ajc.Main
final def variants = project.android.applicationVariants
variants.all { variant ->
JavaCompile javaCompile = variant.javaCompile
javaCompile.doLast {
String[] args = ["-showWeaveInfo",
"-1.5",
"-inpath", javaCompile.destinationDir.toString(),
"-aspectpath", javaCompile.classpath.asPath,
"-d", javaCompile.destinationDir.toString(),
"-classpath", javaCompile.classpath.asPath,
"-bootclasspath", android.bootClasspath.join(
File.pathSeparator)]
MessageHandler handler = new MessageHandler(true)
new Main().run(args, handler)
def log = project.logger
for (IMessage message : handler.getMessages(null, true)) {
switch (message.getKind()) {
case IMessage.ABORT:
case IMessage.ERROR:
case IMessage.FAIL:
log.error message.message, message.thrown
break
case IMessage.WARNING:
case IMessage.INFO:
log.info message.message, message.thrown
break
case IMessage.DEBUG:
log.debug message.message, message.thrown
break
}
}
}
}
注意:在哪使用就需要在哪配置上面的一大段东西,网络上也有自定义Puglin进行组件化的操作,就不用每个都去设置,但是自己尝试了报错。
2.MianActivity代码
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = findViewById(R.id.tv);
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showToast();
}
});
}
private void showToast(){
Toast.makeText(MainActivity.this,"aaaaaaaaaaa",Toast.LENGTH_SHORT).show();
}
}
3.调用AspectJ
@Aspect
public class AspectJText {
@Before("execution(* com.example.aspectjdemo.MainActivity.showToast(..))")
public void show(JoinPoint joinPoint){
Toast.makeText((Context) joinPoint.getThis(), "hhhhhh", Toast.LENGTH_SHORT).show();
}
final String TAG = AspectJText.class.getSimpleName();
@Before("execution(* *..MainActivity+.on**(..))")
public void method(JoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
String className = joinPoint.getThis().getClass().getSimpleName();
Log.e(TAG, "class:" + className);
Log.e(TAG, "method:" + methodSignature.getName());
}
}
运行结果:
?编译后文件:
?可以看到编译后的类文件出现了AspectJ动态加上的语句。
|