代理模式简单的讲就是创建一个代理对象,然后通过代理对象来访问目标对象,完成原来的任务。这样可以在不改变原有的代码的情况下,增加额外的功能,也就是扩展原来的目标对象的功能。
1.静态代理
在编译阶段就确定了代理目标对象,也就是专为一个类进行代理。
interface BookSell{ //代理接口
void sellBook(int x);
}
class BookProducer implements BookSell{ //被代理类
@Override
public void sellBook(int x) {
System.out.println("有"+x+"本书要卖。");
}
}
class BookAgent implements BookSell{ //静态代理类
private BookProducer bookProducer=new BookProducer(); //静态被代理类创建对象
@Override
public void sellBook(int x) {
System.out.println("给每本书定价。");
bookProducer.sellBook(x);
System.out.println("计算卖了多少书及总金额。");
}
public void bookAdd(int s){
System.out.println("增加了"+s+"本书");
}
}
public class MyProxy {
public static void main(String[] args) throws Throwable {
//静态代理
BookSell bookAgent = new BookAgent();
bookAgent.sellBook(50);
System.out.println("========================");
}
}
2.动态代理
在运行阶段确定代理的对象,通用性更强。
-
JDK动态代理
被代理的类需要实现代理接口,还需要一个代理处理器。
interface BookSell{ //代理接口 void sellBook(int x); } class BookProducer implements BookSell{ //被代理类 @Override public void sellBook(int x) { System.out.println("有"+x+"本书要卖。"); } } class theAgent implements InvocationHandler{ //实现InvocationHandler接口的代理处理器类 private Object target; public theAgent(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("sellBook")){ System.out.println("给每本书定价。"); method.invoke(target, args);//使用反射执行代理对象方法 System.out.println("计算卖了多少书及总金额。"); } return null; } } public class MyProxy { public static void main(String[] args) throws Throwable { //JDK动态代理方法一 BookProducer bookProducer = new BookProducer(); //被动态代理对象 theAgent agentHandler = new theAgent(bookProducer); //创建代理处理器 //构造实现指定接口的代理类的一个实例对象 BookSell bookSell = (BookSell) Proxy.newProxyInstance(MyProxy.class.getClassLoader(), new Class[]{BookSell.class}, agentHandler); bookSell.sellBook(50); //代理对象实现方法 /*实现细节 Object invoke = agentHandler.invoke(bookProducer, BookProducer.class.getMethod("sellBook",int.class), new Integer[]{Integer.valueOf(50)}); */ System.out.println("============================="); //JDK动态代理方法二 Class agentProxyClass = Proxy.getProxyClass(MyProxy.class.getClassLoader(), BookSell.class); //创建事先指定接口代理类 BookSell bookSell1 = (BookSell) agentProxyClass.getConstructor(InvocationHandler.class).newInstance(agentHandler); //创建代理类对象 bookSell1.sellBook(100); System.out.println("======================="); } }
-
CGLib动态代理
被代理的类不需要实现代理接口,但需要实现MethodInterceptor接口,该接口需要引入cglib.jar。
<!-- maven --> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
class BookPrint{ public void sellBook(int x) { System.out.println("有"+x+"本书要卖。"); } } class BookPrintProxy implements MethodInterceptor{ Object target; public BookPrintProxy(Object target) { this.target = target; } @Override public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { if (method.getName().equals("sellBook")){ System.out.println("给每本书定价。"); method.invoke(target, args);//使用反射执行代理对象方法 System.out.println("计算卖了多少书及总金额。"); } return null; } } public class MyProxy { public static void main(String[] args) throws Throwable { //CGLib代理模式(被代理类不需要继承接口) BookPrint bookPrint = new BookPrint(); BookPrintProxy bookPrintProxy = new BookPrintProxy(bookPrint); BookPrint b= (BookPrint) Enhancer.create(BookPrint.class,bookPrintProxy); b.sellBook(200); } }