JAVA 代理之 JDK 代理与 CGLIB 代理

#1. 代理模式
代理模式是 JAVA 的一种设计模式,形成条件如下:
a. 客户端不能直接调用目标类的时候,让客户端调用目标类的代理类
b.代理类和目标类实现相同的接口
c. 代理类将所有的方法调用分派到目标对象上,且可添加前置通知(校验等)和后置处理(打印日志等)
代理可分为静态代理和动态代理

#2. 静态代理
由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了
a. 接口声明及实现
public interface Account {
	public String queryAccount();
}
public class AccountImpl implements Account{
	@Override
	public String queryAccount() {
		System.out.println("查询成功");
		return null;
	}

}
b. 创建代理类并实现接口
public class AccountProxy implements Account{
	private AccountImpl accountImpl;
	public AccountProxy(AccountImpl accountImpl) {
		super();
		this.accountImpl = accountImpl;
	}
	@Override
	public String queryAccount() {
		System.out.println("...前置通知...");
		accountImpl.queryAccount();
		System.out.println("...后置处理...");
		return null;
	}

}
c. 调用
public class TestProxy {
	public static void main(String[] args) {
		AccountProxy ap = new AccountProxy(new AccountImpl());
		ap.queryAccount();
	}
}

由于只能一个代理对应一个接口,易产生多个代理类,固换下方动态代理

#3. 动态代理

##1. JDK 动态代理(使用InvocationHandler接口和Proxy类)

在程序运行时,运用反射机制动态创建

a. 接口声明及实现
public interface Account {
	public String queryAccount();
}
public class AccountImpl implements Account{
	@Override
	public String queryAccount() {
		System.out.println("查询成功");
		return null;
	}

}

b. 创建代理类并实现接口

public class AccountProxy implements InvocationHandler{
	private Object target;
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object result = null;
		System.out.println("...代理start...");
		result = method.invoke(target, args);
		System.out.println("...代理end...");
		return result;
	}
	public Object bind(Object target){
		this.target = target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
	}
}
c. 调用

public class TestProxy {
	public static void main(String[] args) {
		AccountProxy ap = new AccountProxy();
		Account account = (Account)ap.bind(new AccountImpl());
		account.queryAccount();
	}
}

JDK 动态代理依靠接口实现,如果有些类并没有实现接口,就要使用 CGLIB 动态代理

##2. CGLIB 动态代理(使用MethodInterceptor接口和Enhancer类)

CGLIB 的底层采用ASM字节码生成,比 JDK 代理效率高

a. 创建类
public class Account {
	public String queryAccount();
}
b. 创建代理类并实现接口
public class AccountProxy implements MethodInterceptor{
	private Object	target;
	@Override
	public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable {
		Object result = null;
		System.out.println("...代理start...");
		result = proxy.invokeSuper(obj, arg);
		System.out.println("...代理end...");
		return result;
	}
	public Object bind(Object target){
		this.target = target;
		Enhancer eh = new Enhancer();
		eh.setSuperclass(this.target.getClass());
		eh.setCallback(this);
		return eh.create();
	}
}
c. 调用
public class TestProxy {
	public static void main(String[] args) {
		AccountProxy ap = new AccountProxy();
		Account account = (Account)ap.bind(new Account());
		account.queryAccount();
	}
}
因为采用的是继承,所以CGLIB不能代理final类
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值