1、代理模式
为其他对象提供代理以控制这个对象的访问。
特点:代理对象和被代理对象都实现同一接口,代理对象可以为被代理对象的行为添加额外的动作(预处理消息、过滤消息、事后处理等)。
按照代理的创建时期,分两类:
静态代理:在运行前,代码已编译成class文件。
动态代理:在运行时,通过反射机制动态创建。
2、静态代理示例
接口:
package proxy;
public interface Count {
void count();
void print();
}
实现类:
package proxy;
public class CountImpl implements Count{
public void count() {
System.out.print(this.getClass().getName()+" 执行count计数!");
}
public void print() {
System.out.println(this.getClass().getName()+" 显示结果!");
}
}
代理类:
package proxy;
public class ProxyCount implements Count{
private Count count;
public ProxyCount(Count count){
this.count = count;
}
public void count() {
System.out.println("找人代计数开始:");
count.count();
System.out.println("找人代计数结束!");
}
public void print() {
System.out.println("包装显示开始:");
count.print();
System.out.println("包装显示结束!");
}
}
3、java动态代理示例
和动态代理相关的两个java类:
InvocationHandler类:
package java.lang.reflect;
public interface InvocationHandler
{
public Object invoke(Object object, Method method, Object[] objects)
throws Throwable;
}
第一个参数object:指被代理的对象;第二个参数method:要调用的方法;第三个参数objects:方法调用所需要的参数。
Proxy类:
public static Object newProxyInstance
(ClassLoader classloader, Class[] var_classes,
InvocationHandler invocationhandler)
// 用于关联代理对象
示例:
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynaProxyCount implements InvocationHandler{
private Object object;
public DynaProxyCount(Object object){
this.object = object;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(this.object, args);
after();
return result;
}
private void before(){
System.out.println("调用方法之前执行!");
}
private void after(){
System.out.println("调用方法之后执行!");
}
}
测试类:
package proxy;
import java.lang.reflect.Proxy;
public class TestDynaProxy {
/**
* @param args
*/
public static void main(String[] args) {
// TODO 自动生成方法存根
Count count = new CountImpl();
DynaProxyCount handler = new DynaProxyCount(count);
Count proxy = (Count)Proxy.newProxyInstance(count.getClass().getClassLoader(),count.getClass().getInterfaces(),handler);
proxy.count();
proxy.print();
}
}
4、cglib动态代理示例
jdk动态代理只提供了接口的代理,没有针对类的代理。cglib动态代理的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
示例:
package proxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibProxyCount implements MethodInterceptor{
private Object object;
public Object getInstance(Object obj){
this.object = obj;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.object.getClass());
// 回调
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
before();
Object result = proxy.invokeSuper(obj, args);
after();
return result;
}
private void before(){
System.out.println("调用方法之前执行!");
}
private void after(){
System.out.println("调用方法之后执行!");
}
}
测试类:
package proxy;
public class TestCglibProxy {
public static void main(String[] args){
CglibProxyCount proxy = new CglibProxyCount();
Count count = (Count)proxy.getInstance(new CountImpl());
count.count();
count.print();
}
}