核心作用:
通过代理,控制对对象的访问。可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。
代理也是AOP(Aspect Oriented Programming面向切面编程)的核心实现机制!
AOP(Aspect-Oriented Programming,面向切面的编程)
– 它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。它是一种新的方法论,它是对传统OOP编程的一种补充。
AOP常用术语:
– 切面(Aspect):其实就是共有功能的实现。
– 通知(Advice):是切面的具体实现。
– 连接点(Joinpoint):就是程序在运行过程中能够插入切面的地点。
– 切入点(Pointcut):用于定义通知应该切入到哪些连接点上。
– 目标对象(Target):就是那些即将切入切面的对象,也就是那些被通知的对象
– 代理对象(Proxy):将通知应用到目标对象之后被动态创建的对象。
– 织入(Weaving):将切面应用到目标对象从而创建一个新的代理对象的过程。
代理模式的三个核心角色:
抽象角色:代理角色和真实角色都实现的接口,定义代理角色和真实角色的公共对外方法。
真实角色:被代理的类
代理类:代理类中的方法由真实角色中的方法逻辑和前后处理构成。
应用场景:
– 安全代理:屏蔽对真实角色的直接访问。
– 远程代理:通过代理类处理远程方法调用(RMI)
– 延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象。
开发框架中应用场景:
– struts2中拦截器的实现
– 数据库连接池关闭处理
– Hibernate中延时加载的实现
– mybatis中实现拦截器插件
– AspectJ的实现
– spring中AOP的实现
• 日志拦截
• 声明式事务处理
– web service
– RMI远程方法调用
分类:
– 静态代理(静态定义代理类)
– 动态代理(动态生成代理类)
• JDK自带的动态代理
• javaassist字节码操作库实现
• CGLIB
• ASM(底层使用指令,可维护性较差)
1、静态代理
抽象角色:Car
public interface Car {
void run();
void stop();
}
真实角色:RealCar
public class RealCar implements Car {
@Override
public void run() {
System.out.println("汽车在跑!");
}
@Override
public void stop() {
System.out.println("停车!");
}
}
代理角色:ProxyRealCar
public class ProxyRealCar implements Car {
private RealCar RealCar = new RealCar();
@Override
public void run() {
System.out.print("代理");
RealCar.run();
}
@Override
public void stop() {
System.out.print("代理");
RealCar.stop();
}
}
测试:
public class Client {
public static void main(String[] args) {
Car proxyCar = new ProxyRealCar();
proxyCar.run();
proxyCar.stop();
}
}
2、动态代理
动态代理相比于静态代理的优点
当静态代理中真实角色方法太多的时候,写起代理角色的方法就比较繁琐,需要在每个代理对象中写前后处理和调用真实角色的方法;如果使用动态代理,就可以把要所有前后处理和调用真实角色代码写到同一个方法中,简化了代码的书写。
JDK自带的动态代理
– java.lang.reflect.Proxy
• 作用:动态生成代理类和对象
– java.lang.reflect.InvocationHandler(处理器接口)
• 可以通过invoke方法实现对真实角色的代理访问。
• 每次通过Proxy生成代理类对象对象时都要指定对应的处理器对象
动态代理不需要我们自己写代理对象,由方法生成。但我们需要多写一个Handler,具体如下代码:
抽象角色:Car
public interface Car {
void run();
void stop();
}
真实角色:RealCar
public class RealCar implements Car {
@Override
public void run() {
System.out.println("汽车在跑!");
}
@Override
public void stop() {
System.out.println("停车!");
}
}
CarHandler:
public class CarHandler implements InvocationHandler {
private Car ReaCar = new RealCar();
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.print("代理");
method.invoke(ReaCar, args);
return null;
}
}
动态生成代理对象:
public class Client {
public static void main(String[] args) {
CarHandler carHandler = new CarHandler();
Car proxy = (Car) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), RealCar.class.getInterfaces(), carHandler);
proxy.run();
proxy.stop();
}
}