1, Introduction and usage scenarios
aspectJ It is an open source tool in the eclipse community. It can seamlessly expand the aspect oriented java programming language and is fully compatible with the java language. It can gracefully deal with the concerns, such as error checking and processing, performance optimization, monitoring and logging. When it comes to aspect oriented programming, you may think of the famous spring AOP, which is implemented based on the dynamic proxy pattern. The agent mode is divided into static agent and dynamic agent. The static agent modifies the code during compilation and injects the specified object into the code, which has poor expansibility and strong coupling; The dynamic agent dynamically obtains objects and calls their methods through reflection at runtime, which is inefficient and highly coupled. Spring AOP solves the coupling problem to a certain extent through IOC dependency injection technology, but the execution efficiency has not been solved; aspectJ modifies the code during compilation and is separated from the business logic code. It has strong coupling and does not affect the efficiency of runtime. JakeWharton Great God's function is time-consuming to monitor open source projects hugo aspectJ technology is used.
2, Basic concepts
2.0 notes
stay Manually implement bindview An article uses annotations. Now more and more people feel that annotations are very useful. For the specific use of annotations, please refer to my previous articles annotation Here I create a runtime annotation.
//CheckNet.java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface CheckNet { }
2.1 Aspect
Aspect is a collection of pointcuts and notifications, @ aspect uses it to declare a class to represent an aspect that needs to be executed. For example, I create a class here and add @ aspect annotation at the top of the class.
//MyAspect.java @Aspect public class MyAspect { }
2.2 PointCut entry point
Pointcuts, also known as trigger conditions, refer to those connection points that want to cut into Advice filtered by using some specific expressions, @ Pointcut declares a Pointcut.
Here I want to make a logic of network judgment
//MyAspect.java @Pointcut("execution(@com.shan.aspectjapp.CheckNet * *(..))") public void checkNetAction(){ }
In Pointcut, I use execution, that is, taking the execution time of the method as the tangent point to trigger the Aspect class. The string in execution is a trigger condition and a specific cut-off point. Let me explain the composition of the parameters. "execution(@com.shan.aspectjapp.CheckNet * *(..))" This condition is that all methods or attributes annotated with checknet will be tangent points, with a wide range.
- **: indicates any package name
- ..: represents any number of parameters of any type
2.3 Advice notice
Notification is the code implementation method injected into the pointcut, @ Before/@After/@Around / (collectively referred to as Advice type) declares that the slice code is executed before, after and in the tangent point. See the following table for details:
Before | Pre notification: the notification is executed before the target is executed |
After | Post notification |
Around | Surround the notice, execute the notice in the target execution, and control the target execution time |
AfterReturning | The post return notification is executed when the target returns |
AfterThrowing | Exception notification, which is executed when the target throws an exception |
Here @ Around is used to judge whether there is a network when the object code is executed. If there is no network, the target method will not be executed, otherwise the target method will be executed
@Around("checkNetAction()") public Object checkNet(ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); CheckNet checkNet = signature.getMethod().getAnnotation(CheckNet.class); LogUtil.d("checkNet,"+checkNet); if (checkNet!=null) { if (!isNetworkAvailable()) { Toast.makeText(MyApp.getContext(),"please check your network",Toast.LENGTH_SHORT).show(); return null; //If there is no network, the target method will not continue to execute } } return joinPoint.proceed(); //If there is a network, continue to execute the target method }
2.4 Joint Point
All target methods are join points
2.5 Weaving weaving
It mainly uses AJC to inject the cutting code into the target at compile time and generate the mixed code class process
3, Used in android
3.1 download and install aspectJ
You can download aspectJ.com from aspectJ's official website jar, and then two computers go all the way to next until the installation is successful. I downloaded version 1.9.6 here. After installation, I found aspectjrt. Com in the installation directory jar will be used later in android project.
3.2 configuring android dependencies
First, the project root directory build Add aspectJ dependency to gradle
//build.gradle // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ...... dependencies { classpath "com.android.tools.build:gradle:4.2.1" //The focus is on the following two lines classpath 'org.aspectj:aspectjtools:1.9.6' classpath 'org.aspectj:aspectjweaver:1.9.6' } }
Then, in the build.exe of the main module Gradle add dependencies and environments
//build.gradle plugins { id 'com.android.application' } //Focus on the following three lines import org.aspectj.bridge.IMessage import org.aspectj.bridge.MessageHandler import org.aspectj.tools.ajc.Main ...... //Then there's a lump down there final def log = project.logger final def variants = project.android.applicationVariants variants.all { variant -> if (!variant.buildType.isDebuggable()) { log.debug("Skipping non-debuggable build type '${variant.buildType.name}'.") return; } JavaCompile javaCompile = variant.javaCompile javaCompile.doLast { String[] args = ["-showWeaveInfo", "-1.8", "-inpath", javaCompile.destinationDir.toString(), "-aspectpath", javaCompile.classpath.asPath, "-d", javaCompile.destinationDir.toString(), "-classpath", javaCompile.classpath.asPath, "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)] log.debug "ajc args: " + Arrays.toString(args) MessageHandler handler = new MessageHandler(true); new Main().run(args, handler); 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: log.warn message.message, message.thrown break; case IMessage.INFO: log.info message.message, message.thrown break; case IMessage.DEBUG: log.debug message.message, message.thrown break; } } } }
Finally, aspectjrt Put jar in libs directory and add dependency
3.3 use
Then click login in activity. If there is no network, the following "we will surf the Internet" prompt will not go to, but myaspect "please check your network" in Java; If there is a network, you will be prompted "we will surf the Internet"
//MainActivity.java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @CheckNet //This is aspect oriented programming public void login(View view) { Toast.makeText(this,"we will surf the Internet",Toast.LENGTH_SHORT).show(); } }
Reference: