代理模式
一、知识点和用法案例
1.概念
代理模式简介:
代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
作用:
中介的作用,当调用者不能或不方便调用某个对象时,代理起到中介的作用,帮助调用者间接的调用对象。
分类:
静态代理(运行前)和动态代理(运行后反射调用)
静态代理步骤:
1)代理者和被代理者都实现相同的接口
2)代理者包含被代理者的对象
3)创建代理对象时传入被代理对象
4)代理者执行方法时,会调用被代理者的方法,同时扩展新的功能
动态代理:
分类:JDK代理和CGLib动态代理
JDK代理步骤:
1) 实现InvocationHandler接口
2)实现invoke方法
3)通过Proxy.newProxyInstance方法返回代理对象
CGLib动态代理步骤:
1)引入cglib
2)实现MethodInterceptor接口
3)实现intercept方法
4)通过Ehancer返回代理对象
2.代码案例
静态代理:
package com.hp.staticproxy;
public interface CellphoneSalary {
void sell(String brand);
}
package com.hp.staticproxy;
public interface ComputerSalary {
void sell(String brand);
}
package com.hp.staticproxy;
public class CellphoneFactory implements CellphoneSalary{
public void sell(String brand) {
System.out.printf("工厂卖%s牌子手机\n",brand);
}
}
package com.hp.staticproxy;
public class CellphoneShop implements CellphoneSalary{
//被代理的工厂对象
private CellphoneSalary factory;
//创建代理者对象时传入被代理对象
public CellphoneShop(CellphoneSalary factory) {
this.factory = factory;
}
public void sell(String brand) {
//扩展
System.out.printf("为%s手机打广告\n",brand);
//调用被代理者原来的功能
factory.sell(brand);
System.out.printf("为%s手机做售后\n",brand);
}
}
package com.hp.staticproxy;
public class ComputerFactory implements ComputerSalary{
public void sell(String brand) {
System.out.printf("工厂卖%s牌子的电脑\n",brand);
}
}
package com.hp.staticproxy;
public class ComputerShop implements ComputerSalary{
//被代理的工厂对象
private ComputerSalary factory;
//创建代理者对象时传入被代理对象
public ComputerShop(ComputerSalary factory) {
this.factory = factory;
}
public void sell(String brand) {
//扩展
System.out.printf("为%s电脑打广告\n",brand);
//调用被代理者原来的功能
factory.sell(brand);
System.out.printf("为%s电脑做售后\n",brand);
}
}
测试:
package com.hp.staticproxy;
public class TestProxy {
public static void main(String[] args) {
CellphoneSalary factory = new CellphoneFactory();
ComputerFactory factory1 = new ComputerFactory();
ComputerSalary shop1 = new ComputerShop(factory1);
CellphoneSalary shop = new CellphoneShop(factory);
factory.sell("华为");
shop.sell("华为");
factory1.sell("华硕");
shop1.sell("华硕");
}
}
JDK动态代理:
package com.hp.jdknamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
* 万能代理商
* */
public class JdkShop implements InvocationHandler {
//定义一个被代理的对象
private Object target;
public Object newProxyInstance(Object target){
this.target=target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//功能扩展
System.out.println("商店帮忙打广告!!");
//调用被代理者方法
Object invoke = method.invoke(target, args);
System.out.println("商店帮忙做售后!!");
return invoke;
}
}
测试:
package com.hp.jdknamicproxy;
import com.hp.staticproxy.CellphoneFactory;
import com.hp.staticproxy.CellphoneSalary;
import com.hp.staticproxy.ComputerFactory;
import com.hp.staticproxy.ComputerSalary;
public class TestShop {
public static void main(String[] args) {
CellphoneSalary factory = new CellphoneFactory();
ComputerSalary factory1 = new ComputerFactory();
JdkShop shop = new JdkShop();
CellphoneSalary o = (CellphoneSalary) shop.newProxyInstance(factory);
o.sell("华为");
ComputerSalary o1 = (ComputerSalary) shop.newProxyInstance(factory1);
o1.sell("华硕");
}
}
CGLib动态代理:
package com.hp.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/*
* CGlib动态代理
* */
public class CGlibProxy implements MethodInterceptor {
//被代理对象
private Object target;
public Object createProxy(Object target){
this.target=target;
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(this.target.getClass());
//设置方法回调MethodInterceptor实现
enhancer.setCallback(this);
//返回代理对象
return enhancer.create();
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//扩展
System.out.println("CGLib商店打广告!");
//调用原来方法
Object invoke = method.invoke(target, objects);
System.out.println("CGLib商店做售后!");
return invoke;
}
}
测试:
package com.hp.cglib;
import com.hp.staticproxy.CellphoneFactory;
import com.hp.staticproxy.CellphoneSalary;
public class TestCGLib {
public static void main(String[] args) {
CellphoneSalary factory = new CellphoneFactory();
CGlibProxy proxy = new CGlibProxy();
CellphoneSalary o = (CellphoneSalary) proxy.createProxy(factory);
o.sell("华为");
}
}
总结
以上就是代理模式相关的所有知识和用法。