Java中的动态代理:
对原有类中的方法进行功能的增强。
Connection接口。它中提供的close方法,可以将数据库的连接关闭。而真正在使用的数据库连接的时候,不能一直创建连接,用完就直接关闭连接,这样消耗数据库的资源(性能)。
创建一个连接池对象(集合),在连接池初始化的时候,就手动的创建指定数额的数据库连接。在有人需要使用数据库的时候,从连接池中将连接取出,交给使用者。在使用者使用完之后,应该把连接归还给连接池。
归还连接,就需要在连接池上定义归还连接的方法,这样导致程序员在书写数据库操作的代码中要使用其他的方法。这样不方便使用,因此我们手动的修改Connection接口中的close方法。目的是让程序员依然调用close方法关闭连接,但是真正在调用close方法的时候,会被我们的代理程序处理,而没有真正的关闭连接,而是将连接归还给的连接池。
对类中的方法增强的方式:
1、动态代理
2、包装
BufferedReader(Reader )
BufferedReader bufr = new BufferedReader( new FileReader(“文件”) );
3、 继承,复写需要增强的方法,不推荐
java语法要求被代理类中需要被代理的方法都别抽象成一个接口
package cn.wang.peoxy;
/**
* JAVA语言规定需要被代理的类的方法,必须被抽象出来!!!
*
* @author Administrator
*
*/
public interface Inter {
public abstract void dance();
public abstract void sing(String name);
}
被代理类
package cn.wang.peoxy;
/*
* 范冰冰类是要被代理的类,java规定要被代理的类的方法,都需要被抽象出来
*
*/
public class FanBing implements Inter {
/*
* (non-Javadoc)
*
* @see cn.wang.peoxy.inter#dance()
*/
@Override
public void dance() {
System.out.println("跳舞");
}
/*
* (non-Javadoc)
*
* @see cn.wang.peoxy.inter#sing()
*/
@Override
public void sing(String name) {
System.out.println("唱《" + name + "》歌");
}
public void sleep() {
System.out.println("睡觉");
}
}
代理类
package cn.wang.peoxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
* 代理的方法,代理范冰冰!!
*/
public class ProxyClass {
// 1.首先要创建一个被代理类的对象
private static final FanBing FBB = new FanBing();
// 2.创建一个方法让其他方法来获取被代理类的对象
public static Object getProxyInstance() {
Object obj = Proxy.newProxyInstance(
// 获取负责加载ProxyClass类的那个加载器对象
ProxyClass.class.getClassLoader(),
// 获取被代理类实现的所有接口,通过被代理类的字节码文件后去被代理类实现的所有接口
FBB.getClass().getInterfaces(),
new InvocationHandler() {
/*
* Object proxy 代理对象
*
* Method method 被代理类被调用的方法
*
* Object[] args 调用方法 传递的参数
*
* invoke()是由jvm调用,外界无论调用被代理类的声明方法,都会执行involk()方法,这样就可以在里面做判断了
*/
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
if ("dance".equals(method.getName())) {
// 调用的是被代理类的dance方法,应该让让被代理类的dance方法执行
return method.invoke(FBB, args);
}
if ("sing".equals(method.getName())) {
// 调用的是被代理类的sing方法,应该让被代理类去执行
return method.invoke(FBB, args);
}
// 说明调用的不是被代理的方法
return "本大爷不代理其他方法";
}
});
return obj;
}
}
测试类
/*
* 测试类
*/
public class ProxyTest {
public static void main(String[] args) {
// 1.获取被代理类的方法,但是不能new,需要通过代理类来获得
Object object = ProxyClass.getProxyInstance();
// 2.把获取到的对象强制转换为接口类型
Inter i = (Inter) object;
// 2.调用被代理类当中的方法
System.out.println(i.toString());// 相当于调用了i的tostring方法
i.dance();
i.sing("风往北吹");
}
}
运行结果
本大爷不代理其他方法
跳舞
唱《风往北吹》歌