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修饰的类进行代理。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值