JAVA learning diary: dynamic agent mode

Dynamic proxy mode

Today's main content:
all are dry goods, it is not easy to organize! Please like everyone who passed by!
You can take the code used in the example at will. It is suitable for students who have learned the reflection mechanism of java . If you have not studied before, there is a study diary compiled by myself of the reflection mechanism of java on my blog homepage for viewing.
Today we want to understand AOP in a shallow level, which is the first time for me The cute new person who came into contact with this thing was a little flustered
. There may be something wrong with the summed up. Hope the passing gods can point it out! Grateful!

理解面向切面编程AOP:
		AOP全称:Aspect Oriented Programming
		将散落在业务逻辑各个角落的、具有横切性特点的代码在合适的切入点、合适的时机切入到目标代码的执行过程中去,实现与业务逻辑的分离、解耦,更加便于维护、管理
	
		反射机制->动态代理模式->AOP
		
java中动态代理模式的实现:
		动态代理的核心类及接口:
			java.lang.reflect.InvocationHandler
			java.lang.reflect.Proxy

Next, we will use an example of buying a house to explain what is the dynamic agency model:

We use three classes, one interface:

		1.Owner类:找代理人的人,业主
		
		2.Buyable接口:代理人能做的方法,也是要被横向织入的各种方法的集合
					   所以这里Owner implements Buyable
					   
		3.OwnerProxyInvocationHandler类:业主代理的调用处理器			
					   一般这个代理类都要实现一个接口叫InvocationHandler
					   通俗的将这个类是用来实现横向织入过程的,将业主要
					   被代理使用但不更改原来方法的动作在这个类里待命
					   
		4.Test类:功能测试类

The main implementation logic of this example (important! Must see!):

	首先我们创建一个Owner类,也就是业主类,业主类接上Buyable能力的接口,
	得到Buyable接口中的方法,然后我们编写一个OwnerProxyInvocationHandler
	类,这个类将业主需要找代理商去做的事情以自己的方式在保留业主的原来方法
	的情况下做出来,然后在测试类里面创建一个代理人,这个代理人实例一般都是
	业主的能力接口的对象。好下面我们开始。

Several important methods in this dynamic proxy example (important! Can be seen with the code):

	1.Proxy.newProxyInstance(ClassLoader loader,  Class<?> interfaces, InvocationHandler h)
			第一个参数:类加载器,就是我们当前所在类的加类载器,例子中为Test.getClass().getClassLoader()
			第二个参数:被代理目标的所有接口,例子里是o1.getClass.getInterfaces()
			第三个参数:代理对象的方法要被哪个类处理就填谁,例子中为new OwnerProxyInvcationHandler(o1)

	2.public Object invoke(Object proxy, Method method, Object[] args) throws Throwable他是InvocationHandler接口中需要重写的方法,也是横向织入的核心方法。
			第一个参数:可以将代理对象返回以进行连续调用,且不断允许反射产生Proxy实例。
			第二个参数:我们需要被代理的哪个对象的方法那个方法被Method封装成了一个对象
			第三个参数:被代理的方法参数

Not much nonsense! Code! (Combining the previous knowledge points to see the better effect)

Owner class:

package LessonForDynamicProxyPattern;

//Owner类此时为被代理对象!
public class Owner implements Buyable 
{
    
    
	@Override
	public void payCash() 
	{
    
    
		System.out.println("---调用payCash()方法---");
	}

	@Override
	public int makeMoney(int amount) 
	{
    
    
		System.out.println("---调用makeMoney(int amount)方法---");
		return amount*1000;
	}
}

OwnerProxyInvocationHandler class:

package LessonForDynamicProxyPattern;

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

public class OwnerProxyInvcationHandler implements InvocationHandler
{
    
    
	/*
	 *public Object invoke(Object proxy, Method method, Object[] args) throws Throwable方法
	 * 	第一个参数:产生了代理实例
	 * 	第二个参数:我们需要被代理的那个方法的对象,那个方法被Method封装成一个对象
	 * 	第三个参数:被代理的方法的参数
	 */
	
	private Object target;//帮忙代理的代理目标
	
	public OwnerProxyInvcationHandler(Object target)
	{
    
    
		super();
		this.target = target;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
	{
    
    
		System.out.println("被代理的方法执行前。。。。。");
		Object result = method.invoke(target, args);
		/*
		 * 	这里第一个参数:是被代理目标
		 * 	这里第二个参数:是被代理方法的参数,如果没有就这样摆着就行了
		 * 	这里有返回值,返回值是什么呢,是被我们代理的目标方法的返回值,我们具体情况具体向下转型
		 */
		System.out.println("被代理方法执行之后我标记了一下");
		
		/*
		 * 	28~35行就是AOP的横切面逻辑,目标方法执行前我们要求有动作,目标方法执行后我们也要求有动作
		 * 	但是这些前后要执行的动作没有被硬写到被代理的目标对象的那个方法中去,实现松耦合
		 */
		
		return result;
	}

}

Buyable interface:

package LessonForDynamicProxyPattern;

public interface Buyable //核心业务接口
{
    
    
	public void payCash();
	
	public int makeMoney(int amount);
}

Test class:

package LessonForDynamicProxyPattern;

import java.lang.reflect.Proxy;

public class Test 
{
    
    
	public static void main(String[] args) 
	{
    
    
		Owner o1 = new Owner();//找代理人的人
		
		/*
		 *Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
		 * 	第一个参数:类加载器,就是我们当前的类,此时为Test.class.getClassLoader()
		 * 	第二个参数:被代理目标的所有接口。在这个例子中为o1.getClass().getInterfaces()
		 * 	第三个参数:代理对象的方法被代理之后。例子中为new OwnerProxyInvcationHandler(o1)
		 * 	
		 * newProxyInstance返回的就是我们的代理对象实例,一般要为我们的接口
		 */
		
		 Buyable by1 = (Buyable)Proxy.newProxyInstance(Test.class.getClassLoader(),
								o1.getClass().getInterfaces(),
								new OwnerProxyInvcationHandler(o1));//新创建一个“代理人”实例
		 
		 by1.payCash();//动态织入过程
		 System.out.println("----------------------------------");
		 int rent = by1.makeMoney(10);
		 System.out.println(rent);
	}

}

部分文字来源于:
咕嘟咖啡杨海滨老师 — 《java编程语言高级特性》
在这里十分感谢老师能够给我带来学习的激情.

2020.10.08
can reprint my study diary but please indicate the source, thank you.
complete!

Guess you like

Origin blog.csdn.net/SIESTA030/article/details/108966505