静态代理
实际逻辑类注入到代理类
生成代理类的对象,然后执行代理类同名的方法, 在这个方法里,代理类可以自己做一些操作.
动态代理
生成一个代理类,然后将实现类注入进来,然后调用注入类的方法时执行业务逻辑.
Test.java 测试接口类
TestImpl.java 测试接口实现类
TestProxy.java 接口代理类
Tester.java 测试类,main方法所在类
package demo;
public interface Test {
public void sayHello(String name);
}
package demo;
public class TestImpl implements Test {
public void sayHello(String name) {
System.out.println("Hello "+name);
}
}
package demo;
import java.lang.reflect.*;
public class TestProxy implements InvocationHandler {
Test iTest = null;
public TestProxy(Test test) { this.iTest = test; }
public Test getTest(){
return(Test)Proxy.newProxyInstance(iTest.getClass().getClassLoader(),
iTest.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
System.out.println("Before invoke sayHello(\""+args[0]+"\")");
Object rst = method.invoke(iTest,args);
System.out.println("After invoke sayHello(\""+args[0]+"\")");
return rst;
}
}
package demo;
public class Tester {
public static void main(String[] args) {
getTest1().sayHello("JAVA接口代理");
System.out.println("====================");
getTest2().sayHello("JAVA接口代理");
}
private static Test getTest1(){
return new TestImpl();
}
private static Test getTest2(){
return new TestProxy(new TestImpl()).getTest();
}
}
===================================
数据库连接池使用代理
public class _Connection implements InvocationHandler {
private final static String CLOSE_METHOD_NAME = "close";
private Connection conn = null;
private boolean inUse = false; //数据库的忙状态
private long lastAccessTime = System.currentTimeMillis();
_Connection(Connection conn, boolean inUse) {
this.conn = conn;
this.inUse = inUse;
}
public Connection getConnection() {//返回数据库连接conn的接管类,以便截住close方法
return (Connection) Proxy.newProxyInstance(
conn.getClass().getClassLoader(),
conn.getClass().getInterfaces(),
this);
}
void close() throws SQLException { //直接关闭连接
conn.close();
}
public boolean isInUse() { return inUse; }
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Object obj = null;
//判断是否调用了close的方法,如果调用close方法则把连接置为无用状态
if (CLOSE_METHOD_NAME.equals(m.getName()))
setInUse(false);
else
obj = m.invoke(conn, args);
//设置最后一次访问时间,以便及时清除超时的连接
lastAccessTime = System.currentTimeMillis();
return obj;
}
public long getLastAccessTime() { return lastAccessTime; }
public void setInUse(boolean inUse) { this.inUse = inUse; }
}
实际逻辑类注入到代理类
生成代理类的对象,然后执行代理类同名的方法, 在这个方法里,代理类可以自己做一些操作.
动态代理
生成一个代理类,然后将实现类注入进来,然后调用注入类的方法时执行业务逻辑.
Test.java 测试接口类
TestImpl.java 测试接口实现类
TestProxy.java 接口代理类
Tester.java 测试类,main方法所在类
package demo;
public interface Test {
public void sayHello(String name);
}
package demo;
public class TestImpl implements Test {
public void sayHello(String name) {
System.out.println("Hello "+name);
}
}
package demo;
import java.lang.reflect.*;
public class TestProxy implements InvocationHandler {
Test iTest = null;
public TestProxy(Test test) { this.iTest = test; }
public Test getTest(){
return(Test)Proxy.newProxyInstance(iTest.getClass().getClassLoader(),
iTest.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
System.out.println("Before invoke sayHello(\""+args[0]+"\")");
Object rst = method.invoke(iTest,args);
System.out.println("After invoke sayHello(\""+args[0]+"\")");
return rst;
}
}
package demo;
public class Tester {
public static void main(String[] args) {
getTest1().sayHello("JAVA接口代理");
System.out.println("====================");
getTest2().sayHello("JAVA接口代理");
}
private static Test getTest1(){
return new TestImpl();
}
private static Test getTest2(){
return new TestProxy(new TestImpl()).getTest();
}
}
===================================
数据库连接池使用代理
public class _Connection implements InvocationHandler {
private final static String CLOSE_METHOD_NAME = "close";
private Connection conn = null;
private boolean inUse = false; //数据库的忙状态
private long lastAccessTime = System.currentTimeMillis();
_Connection(Connection conn, boolean inUse) {
this.conn = conn;
this.inUse = inUse;
}
public Connection getConnection() {//返回数据库连接conn的接管类,以便截住close方法
return (Connection) Proxy.newProxyInstance(
conn.getClass().getClassLoader(),
conn.getClass().getInterfaces(),
this);
}
void close() throws SQLException { //直接关闭连接
conn.close();
}
public boolean isInUse() { return inUse; }
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Object obj = null;
//判断是否调用了close的方法,如果调用close方法则把连接置为无用状态
if (CLOSE_METHOD_NAME.equals(m.getName()))
setInUse(false);
else
obj = m.invoke(conn, args);
//设置最后一次访问时间,以便及时清除超时的连接
lastAccessTime = System.currentTimeMillis();
return obj;
}
public long getLastAccessTime() { return lastAccessTime; }
public void setInUse(boolean inUse) { this.inUse = inUse; }
}