The Java native agent is used to implement the AOP instance

  • 2020-05-27 05:43:57
  • OfStack

When you think of AOP, you're going to think of spring because it's so powerful, but you're going to have to understand that AOP is a programming idea and Spring is just an implementation of AOP.

First of all, baidu down:

In the software industry, AOP stands for Aspect Oriented Programming, which stands for: a technique of programming to the aspect, maintaining program functions through precompilation and dynamic agents at runtime. As a continuation of OOP, AOP is a hot spot in software development, an important part of Spring framework, and a derivative paradigm of functional programming. AOP can be used to isolate each part of the business logic, thus reducing the coupling between the parts of the business logic, improving the reusability of the program, and improving the efficiency of development.

Today, let's start simple AOP functionality with Java native agent.

First, you need to know the basics of reflection, or you may get confused.

Stop wordy, just start rolling

First, let's write a simple interface, AnimalInterface, to declare some basic methods for regulating animals.

These methods include setting the name, getting the name, the call, the attributes (forgive me for not being literate, but actually getting whether it's terrestrial or aquatic or amphibious)


package proxy.imp;
public interface AnimalInterface {
  // Set the name 
  void setName(String name);
  // Get the name 
  String getName();
  // cry 
  void say();
  // Get a habitat sex 
  void getProperty();
}

Then let's implement the interface and create an Dog called xiaohei


package proxy;

import proxy.imp.AnimalInterface;
public class DogImp implements AnimalInterface {
  private String name = " The little black ";
  public DogImp() {
  }
  @Override
  public void setName(String name) {
    this.name = name;
  }
  @Override
  public String getName() {
    return this.name;
  }
  @Override
  public void say() {
    System.out.println(" The dog : Wang wang wang wang .....");
  }
  @Override
  public void getProperty() {
    System.out.println(" A puppy is a land animal , But I can swim ");
  }
}

We can't wait to see how we can achieve something like AOP... .

Let's first create a class named AOPHandle and let it implement InvocationHandler interface. If invoke cannot be used, proxy will be used as the reflection parameter. Because the interface of the proxy object is different from the object, this proxy mechanism is interface oriented. Not for class, if you use proxy, can lead to infinite recursion. Then is the stack overflow, but still can reflect a successful one, it shows a proxy object and the object of agent is not 1 sample, but we can by proxy proxy parameters. The getClass () to obtain class object, and then obtain the proxy class methods and parameters, this also for annotation injection, injection, specific method attribute injection provides an implementation way, about this, let's say behind..


package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class AOPHandle implements InvocationHandler{
  // Save the object 
  private Object o;
  public AOPHandle(Object o) {
    this.o=o;
  }
  /**
   *  This method is called automatically ,Java Dynamic proxy mechanism 
   *  The following parameter is passed in 
   * @param Object proxy  The interface of the proxy object , Unlike objects 
   * @param Method method  Called method 
   * @param Object[] args  The method parameters 
   *  You can't use invoke The use of proxy As a reflection parameter , Because of the interface of the proxy object , Unlike objects 
   *  This proxy mechanism is interface oriented, not class oriented 
   **/
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // Method return value 
    Object ret=null;
    // Print method name 
    System.err.println(" Execution method :"+method.getName()+"n The parameter type is :");
    // Printing parameters 
    for(Class type:method.getParameterTypes())
      System.err.println(type.getName());
    // Print return type 
    System.err.println(" Return data type :"+method.getReturnType().getName());
    // Reflection call method 
    ret=method.invoke(o, args);
    // End of the statement 
    System.err.println(" Method execution ends ");
    // Returns the return value of the reflection calling method 
    return ret;
  }
}

Dynamic proxy is done.. Then there's our AnimalFactory... Let's continue to


package proxy;
import java.lang.reflect.Proxy;
public class AnimalFactory {
  /***
   *  Get object method 
   * @param obj
   * @return
   */
  private static Object getAnimalBase(Object obj){
    // Get the proxy object 
    return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
        obj.getClass().getInterfaces(), new AOPHandle(obj));
  }
  /***
   *  Get object method 
   * @param obj
   * @return
   */
  @SuppressWarnings("unchecked")
  public static T getAnimal(Object obj){
    return (T) getAnimalBase(obj);
  }
  /***
   *  Get object method 
   * @param className
   * @return
   */
  @SuppressWarnings("unchecked")
  public static  T getAnimal(String className){
    Object obj=null;
    try {
      obj= getAnimalBase(Class.forName(className).newInstance());
    } catch (Exception e) {
      e.printStackTrace();
    }
    return (T)obj;
  }
  /***
   *  Get object method 
   * @param clz
   * @return
   */
  @SuppressWarnings("unchecked")
  public static  T getAnimal(Class clz){
    Object obj=null;
    try {
      obj= getAnimalBase(clz.newInstance());
    } catch (Exception e) {
      e.printStackTrace();
    }
    return (T)obj;
  }
}

At last... What's missing? Come here to see the effect...

Ha ha... Small 2, the last dish... Oh no, it's a test class.. Ha ha / / / /


package proxy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import proxy.AnimalFactory;
import proxy.imp.AnimalInterface;

@RunWith(BlockJUnit4ClassRunner.class)
public class AOPTest {

  @Test
  public void Test1() {
    AnimalInterface dog=AnimalFactory.getAnimal(DogImp.class);
    dog.say();
    System.out.println(" My name is "+dog.getName());
    dog.setName("2 The dog son ");
    System.out.println(" My name is "+dog.getName());
  }
}

What the & # 63; What? At the end of the day, it's like this, it's like this. Just capture one of these. What for?...

What AOP, how can I not see the shadow of AOP at 1? How can I get into the custom method? Just 1 syso input. ... .

Okay, let's move on... See how to implement injection custom methods...

First, add an interface, let's call it AOP injection interface. Name it AOPMethod

Create the after and before methods and receive the Object proxy, Method method, Object[] args parameters

So I can do more things... For example, before executing the method, record the class state, and write log. Monitor the xx variable,,,

Open your imagination.


package proxy.imp;
import java.lang.reflect.Method;

public interface AOPMethod{
  // The method executed before the instance method is executed 
  void after(Object proxy, Method method, Object[] args);
  // The method that is executed after the instance method is executed 
  void before(Object proxy, Method method, Object[] args);
}

Then modify the AOPHandle class to add the AOPMethod attribute.

Modify the constructor to get an AOPMethod instance when the class initializes.

Last modified invoke method... .directly on the code ha


package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import proxy.imp.AOPMethod;

public class AOPHandle implements InvocationHandler{
  // Save the object 
  private AOPMethod method;
  private Object o;
  public AOPHandle(Object o,AOPMethod method) {
    this.o=o;
    this.method=method;
  }
  /**
   *  This method is called automatically ,Java Dynamic proxy mechanism 
   *  The following parameter is passed in 
   * @param Object proxy  The interface of the proxy object , Unlike objects 
   * @param Method method  Called method 
   * @param Object[] args  The method parameters 
   *  You can't use invoke The use of proxy As a reflection parameter , Because of the interface of the proxy object , Unlike objects 
   *  This proxy mechanism is interface oriented, not class oriented 
   **/
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object ret=null;
    // Here are the changes 
    this.method.before(proxy, method, args);
    ret=method.invoke(o, args);
    // Here are the changes 
    this.method.after(proxy, method, args);
    return ret;
  }
}

Whoo, it's done, it looks like a problem, cute...

Update the test class...


package proxy;

import java.lang.reflect.Method;

import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import proxy.imp.AOPMethod;
import proxy.imp.AnimalInterface;

@RunWith(BlockJUnit4ClassRunner.class)
public class AOPTest {

  public static void main(String[] args) {

    AnimalInterface dog = AnimalFactory.getAnimal(DogImp.class, new AOPMethod() {
      //  This is before the method is executed AOP Cut to the method 
      public void before(Object proxy, Method method, Object[] args) {
        System.err.println(" I am in " + method.getName() + " Method before execution ");
      }

      //  This is after the method is executed AOP Cut to the method 
      public void after(Object proxy, Method method, Object[] args) {
        System.err.println(" I am in  " + method.getName() + " Method after execution ");

      }
    });
    dog.say();
    String name1=" My name is " + dog.getName();
    System.out.println(name1);
    dog.setName("2 The dog son ");
    String name2=" My name is "+dog.getName();
    System.out.println(name2);
  }
}

Whir, dear friends, does it feel like an injection? Do you feel like you've cut your way in? The & # 63; The & # 63; Ha ha... .

It looks like the first cut is perfect, but something's missing. Oh yeah, missing configuration files like Spring..

That's easy enough, I'll leave it to you to do, just design the XML format, etc., what are you talking about? You can't block custom methods yet.

You can't intercept custom methods like Spring. oh~~NO, methodName, method, Object[] args, Object proxy, Method method, Object[] args, methodName

Of course, this example does not have any practical significance, not to mention a variety of perfect AOP framework, this article only provides you with a way of thinking, but 1 must remember, again the great thing is also 1 point of accumulation

Instance download: http: / / xiazai ofstack. com / 201701 / yuanma JavaAOP_jb51 rar


Related articles: