代理模式
代理模式属于结构型设计模式
静态代理模式
package com.demo.proxy;
/**
* 代理模式
* 结构型设计模式
* 三个角色:真实角色Target、代理角色Proxy、消费者Consumer
* 静态代理模式:
* 代理角色与真实角色耦合性太高,不适用
* 但是理解动态代理的第一步
*下面以房产出租为例:房主、中介、租客一一对应真实、代理、消费者
*/
//租客
interface Person{
void rent();
}
//房主
class Householder implements Person{
public void rent() {
//出租
System.out.println("出租");
}
}
//中介
class Agent implements Person{
private Person householder;
public Agent(Householder householer){
this.householder=householer;
}
public void rent() {
householder.rent();
}
public void sign(){
System.out.println("请签合同");
}
}
//实例
public class StaticProxy {
public static void main(String[] args) {
//实例化代理角色
Agent agent = new Agent(new Householder());
//调用代理角色的方法,但实际是调用真实角色的方法
agent.rent();//出租
//调用代理角色本身方法
agent.sign();//请签合同
}
}
动态代理模式
JDK动态代理
package com.demo.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* JDK动态代理模式
* JDK动态代理的实现关键在于java.lang.reflect.Proxy类
* 其newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)方法是整个JDK动态代理的核心,用于生成指定接口的代理对象。
* 这个方法有三个参数,ClassLoader表示加载动态生成的代理类的类加载器,interfaces代理类需要实现的接口,InvocationHandler调用处理器InvocationHandler
*/
//同样使用房主、中介、租客三位角色,手写调用处理器
class JDKDynamicProxyHandler implements InvocationHandler {
private Person householder;
public JDKDynamicProxyHandler(Person householder) {
this.householder = householder;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
method.invoke(householder, args);
after();
return null;
}
public void before(){
System.out.println("考察一下");
}
public void after(){
System.out.println("决定了");
}
}
//实例
class JDKDynamicProxy {
public static void main(String[] args) {
Person houseHolder = new Householder();
/**
* 通过
* Person.class.getClassLoader() 类加载器 生成代理类的字节码文件
* new Class[]{Person.class}共同实现Person接口 保证真实角色与代理角色的强一致性
* new JDKDynamicProxyHandler(houseHolder)手写的调用处理器 最终调用invoke()进行处理
* 获得代理对象
*/
Person proxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, new JDKDynamicProxyHandler(houseHolder));
proxy.rent();
}
}
CGLIB动态代理
package com.demo.proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* CGLIB动态代理
* JDK动态代理的目标对象必须实现接口,CGLIB动态代理则没有这个限制
* 它是利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
*/
public class CGLIBDynamicProxy implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//.....增加逻辑
Object invokeSuper = methodProxy.invokeSuper(o, objects);
return invokeSuper;
}
}
class Total {
public void paly(){
//........
}
}
class test{
public static void main(String[] args) {
//Enhancer相当于jdk动态代理的Proxy
Enhancer enhancer = new Enhancer();
//设置对应的参数
enhancer.setSuperclass(Total.class);
enhancer.setCallback(new CGLIBDynamicProxy());
//正式创建代理类
Total total = (Total)enhancer.create();
}
}