动态代理_JDK
静态代理:只能用于实现同一接口的类
JDK动态代理:JRE给我们提供类库(java.lang.reflect.InvocationHandler拦截器),不依赖第三方,动态也就是类似于公共方法,你调用它,然后传入相应的值。
具体实现方法:
package spring;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
/**
* 动态代理_JDk:适用于所有接口,也就是说它象一个公共类一样那个接口都可以使用,需要就调
* @author Administrator
*
*/
public class ProxyHandler implements InvocationHandler{
//实际对象
private Object obj;//接收任意类型
public Object bind(Object obj)
{
this.obj = obj;
/**
* 根据实际对象 -> 代理对象
* 参数:
loader - 定义代理类的类加载器
interfaces - 代理类要实现的接口列表
h - 指派方法调用的调用处理程序
*/
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(), this);
}
/*
proxy:1. 可以使用反射获取代理对象的信息(也就是proxy.getClass().getName())。
2. 可以将代理对象返回以进行连续调用,这就是proxy存在的目的,因为this并不是代理对象。
参考:https://blog.csdn.net/bu2_int/article/details/60150319
method:方法的名称
arg:需要传递的参数
*/
@Override
public Object invoke(Object proxy, Method metod, Object[] arg) throws Throwable {
System.err.println("调用方法的对象"+this.obj.getClass().getName());
System.out.println("调用的方法名称"+metod.getName());
System.out.println("调用方法传递的参数"+Arrays.toString(arg));
Object returnValue= metod.invoke(this.obj, arg);//第一参数就是你传入的object对象也就是上面那个,第二个是你传的参数是数组类型哦
System.out.println("调用方法的放回值"+returnValue);
return returnValue;
}
}
测试:
package spring;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
//加载解析applicationContext.xml
//积极加载,在加载与解析xml的同时,即完成所有bean的实例化
ClassPathXmlApplicationContext factory=new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("IOC容器加载完成");
//声明要需要使用代理的bean
IUserDao userDao1= (IUserDao)factory.getBean("userDao1");
//声明动态代理的bean
ProxyHandler proxyHandler=(ProxyHandler) factory.getBean("proxyHandler");
//调用写好的bind方法传入需要代理的对象
IUserDao proxy1= (IUserDao)proxyHandler.bind(userDao1);
//再调用代理对象中要执行的方法就ok了
proxy1.insertUser("詹丹");
proxy1.selectUser();
}
}