JAVA动态代理

最近看JPA,一直纠结于怎么根据Java接口的方法名称、参数和返回值类型动态的实现接口方法的逻辑,于是看了一下JAVA动态代理的实现过程,对Spring动态实现接口方法逻辑进行了模拟。

场景:

1.按照命名规则对JAVA接口方法进行命名;在解析时能够根据方法名称分析出要执行怎样的操作。

2.方法参数。基于接口或泛型命名的接口参数,能够根据接口或对泛型对象的反射获取参数值。

3.方法返回值。方法返回值的处理与方法参数的处理过程类似。

4.JAVA提供基于接口的动态代理,需要的类或接口为:Proxy、InvocationHandler(接口)。具体的代理对象必须实现InvocationHandler接口,在方法invoke方法中根据方法名称、参数和返回值分析要执行的操作,并实现相应的代码逻辑。

5.通过Proxy.newProxyInstance方法关联接口和代理对象,返回接口的实现对象。直接使用接口执行相应的操作。newProxyInstance需要的参数为类装载器代理接口数组执行代理逻辑的代理对象完全可以实现基于接口的代理,不需要接口的实现类

例子:

接口Hello:

package example;
/**
 * Hello接口中有两个多态型式的方法
 */
public interface Hello {
	public String sayHello(String name) ;
	
	public String sayHello(String name,int age) ;
}

 代理对象ProxyTarget:

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


public class ProxyTarget implements InvocationHandler {

	/**
	 * 根据方法名称、参数和返回值类型动态实现方法逻辑<br>
	 * 根据方法的名称实现拦截
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
		
		System.out.println("method before...");
		
		System.out.print("方法->"+method.getReturnType().getName()+" "+method.getName()+"(");
		
		for (int i = 0; i < method.getParameterTypes().length; i++) {
			System.out.print(method.getParameterTypes()[i].getName());
			if(i<method.getParameterTypes().length-1){
				System.out.print(",");
			}
		}
		
		System.out.println(")");
		
		System.out.println("根据方法名称、参数和返回值分析要执行的操作,并实现代码逻辑");
		
		System.out.println("method after...");
		
		return "" ;
	}

}

 测试main代码:

public static void main(String[] args) {
		ProxyTarget proxyTarget = new ProxyTarget() ;
		
		Hello hello = (Hello)Proxy.newProxyInstance(proxyTarget.getClass().getClassLoader(),new Class[]{Hello.class} , proxyTarget) ;
		
		hello.sayHello("lp") ;
		hello.sayHello("lp",27) ;
	}

 以上动态代理Demo是对接口方法逻辑的动态实现,不需要方法的实现对象。将接口实现对象加入代理对象可以实现日志拦截、事务代理等AOP操作。

你可能感兴趣的:(java动态代理)