`

Java代理Proxy

 
阅读更多
特征:代理类和委托类有同样的接口,代理类主要为委托类预处理消息、过滤消息、把消息转发给委托类、以及事后处理消息等,代理类的本身并不能实现特定功能,代理类通过调用委托类对象的相应方法来提供特殊的服务。

按照代理的创建时期可分为两种:静态代理和动态代理

1、静态代理(class文件在运行之前已经生成)
package com.ifs.proxy;

public interface SimpleService {
	
	public void add();
	
	public void del();

}



package com.ifs.proxy;

public class SimpleServiceImpl implements SimpleService{

	public void add() {
		System.out.println("add()----------------");
	}

	public void del() {
		System.out.println("del()----------------");
	}

}


package com.ifs.proxy.state;

import com.ifs.proxy.SimpleService;

public class StaticProxy implements SimpleService {

	private SimpleService simpleService;

	public StaticProxy(SimpleService simpleService) {
		this.simpleService = simpleService;
	}

	public void add() {
		System.out.println("---------------------->before add()");
		this.simpleService.add();
		System.out.println("---------------------->after add()");
	}

	public void del() {
		System.out.println("---------------------->before del()");
		this.simpleService.del();
		System.out.println("---------------------->after del()");
	}

}


测试代码:
package com.ifs.proxy.state;

import com.ifs.proxy.SimpleServiceImpl;

public class TestStaticProxy {
	public static void main(String[] args) {
		StaticProxy proxy = new StaticProxy(new SimpleServiceImpl());
		proxy.add();
		proxy.del();
	}
}


动态代理:动态代理类的字节码在程序运行时由Java反射机制动态生成,既简化的编程工作又提高了软件系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类,java.lang.reflect 中Proxy类和InvocationHandler接口提高动态生成代码类的能力。
2、动态代理 JDK方式 (值针对存在实现接口的类)
复用之前的 SimpleService类和SimpleServiceImpl类
package com.ifs.proxy.jdk;

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

public class JDKProxy implements InvocationHandler{
	
	private Object targetObject;
	
	public Object newProxy(Object targetObject) {//将目标对象传入进行代理  
        this.targetObject = targetObject;   
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(), this);//返回代理对象  
    }  
	
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		checkPression();//一般我们进行逻辑处理的函数比如这个地方是模拟检查权限  
        Object ret = null;      // 设置方法的返回值  
        ret  = method.invoke(targetObject, args);       //调用invoke方法,ret存储该方法的返回值  
        return ret;  
    }  
  
    private void checkPression() {//模拟检查权限的例子  
        System.out.println(">>检查权限  checkPression()!");  
    }

}


测试代码:
package com.ifs.proxy.jdk;

import com.ifs.proxy.SimpleService;
import com.ifs.proxy.SimpleServiceImpl;

public class TestJDKProxy {

	public static void main(String[] args) {
		JDKProxy proxy = new JDKProxy();
		SimpleService simple = (SimpleService) proxy.newProxy(new SimpleServiceImpl());
		simple.add();
	}

}


3、动态代理 CGLIB

package com.ifs.proxy.cglib;

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 CGLIBProxy implements MethodInterceptor {

	private Object targetObject;// CGLib需要代理的目标对象

	public Object createProxyObject(Object targetObject) {
		this.targetObject = targetObject;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(targetObject.getClass());
		enhancer.setCallback(this);
		Object proxyObj = enhancer.create();
		return proxyObj;// 返回代理对象
	}

	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		Object obj = null;
		if ("add".equals(method.getName())) {// 过滤方法
			checkPression();// 检查权限
		}
		obj = method.invoke(targetObject, args);
		return obj;
	}

	private void checkPression() {
		System.out.println(">>检查权限  checkPression()!");
	}
}


测试代码:
package com.ifs.proxy.cglib;

import com.ifs.proxy.SimpleService;
import com.ifs.proxy.SimpleServiceImpl;

public class TestCGLIBProxy {
	public static void main(String[] args) {
		SimpleService simple = (SimpleService) new CGLIBProxy().createProxyObject(new SimpleServiceImpl());
		simple.add();
		simple.del();
	}
}



两者动态代理的区别:
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics