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