代理模式角色如下:
- Subject(抽象主题):代理类和真实主题的共用的接口,提供对外的公共方法;
- RealSubject(真实主题):真正实现业务逻辑的类;
- Proxy(代理主题):用来代理和封装真实主题;要与被真实主题实现相同的抽象主题;
代理模式结构图:
静态代理:
a. 静态代理实现简单,且不侵入原代码,在编译时就已经将接口,被代理类,代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成。
b. 当被代理类需要增加、删除、修改方法的时候,代理类都要同时修改,不易维护。
c. 当需要代理多个类的时候,就需要创建多个代理类,造成代理类过多不易维护。 如果只用一个代理类,势必要实现多个接口,会造成类过于庞大,也不易维护
动态代理:
JDK动态代理
a. 是利用反射机制生成一个实现代理接口的匿名类。
b. 主要是针对接口,要求目标对象必须实现接口,不能针对类。
c. JDK动态代理在运行时动态生成的,编译完成后没有实际的class文件,而是在运 行时在JVM中动态生成类字节码
CGLIB动态代理:
a. 底层采用ASM字节码生成框架,使用字节码技术生成代理类比反射效率高。
b. CGLib动态代理在运行时在内存中动态生成一个子类对象从而实现对目标对象功能的扩展。
c. 针对类,无需实现接口,对指定的类生成一个子类,覆盖其中的方法,达到代理类无侵入。
d. CGLib动态代理是动态生成被代理类的子类,所以被final修饰的方法不能进行CGLib代理。
静态代理代码实现:
编写一个接口 UserService 也就是Subject(抽象主题)以及该接口实现类 UserServiceImpl也就是RealSubject(真实主题)
public interface UserService {
//汇报
public void report();
}
public class UserServiceImpl implements UserService {
//汇报
public void report() {
System.out.println("汇报异常.....");
}
}
编写静态代理类,也就是Proxy(代理主题)
public class StaticProxy implements UserService {
private UserService target;
public StaticProxy(UserService target) {
this.target = target;
}
public void report() {
this.before();
target.report();
this.after();
}
// 调用方法之前执行
private void before() {
System.out.println("发现异常......");
}
// 调用方法之后执行
private void after() {
System.out.println("处理异常.......");
}
}
代码执行
public static void main(String[] args) {
//静态代理方法测试
UserService userService = new UserServiceImpl();
StaticProxy proxy = new StaticProxy(userService);
proxy.report();
}
运行结果
JDK动态代理代码实现:
编写一个接口 UserService 也就是Subject(抽象主题)以及该接口实现类 UserServiceImpl也就是RealSubject(真实主题)
public interface UserService {
//汇报
public void report();
}
public class UserServiceImpl implements UserService {
//汇报
public void report() {
System.out.println("汇报异常.....");
}
}
编写JDK动态代理类,也就是Proxy(代理主题)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxy {
private Object target;// 维护一个目标对象
public JdkProxy(Object target) {
this.target = target;
}
// 为目标对象生成代理对象
public Object getProxyInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object invoke = method.invoke(target, args);
after();
return invoke;
}
});
}
// 调用方法之前执行
private void before() {
System.out.println("JDK动态代理发现异常......");
}
// 调用方法之后执行
private void after() {
System.out.println("JDK动态代理处理异常.......");
}
}
运行程序:
public static void main(String[] args) {
//JDK动态代理方法测试
UserService userService = new UserServiceImpl();
UserService proxy = (UserService) new JdkProxy(userService).getProxyInstance();
proxy.report();
}
结果查看
CGLIB动态代理代码实现
导入坐标
cglib
cglib
3.2.5
编写一个UserService类也就是RealSubject(真实主题) 无需实现接口,无需实现接口
public class UserService {
//汇报
public void report() {
System.out.println("CGLIB动态代理汇报异常.....");
}
}
编写CGLIB动态代理类,也就是Proxy(代理主题)
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
private Object target;//维护一个目标对象
public CglibProxy(Object target) {
this.target = target;
}
//为目标对象生成代理对象
public Object getProxyInstance() {
//工具类
Enhancer en = new Enhancer();
//将目标类设置父类
en.setSuperclass(target.getClass());
//设置回调函数
en.setCallback(this);
//创建代理对象
return en.create();
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
before();
Object invoke = method.invoke(target, objects);
after();
return invoke;
}
// 调用方法之前执行
private void before() {
System.out.println("CGLIB动态代理发现异常......");
}
// 调用方法之后执行
private void after() {
System.out.println("CGLIB动态代理处理异常.......");
}
}
运行程序:
public static void main(String[] args) {
//CGLib动态代理方法测试
UserService userService = new UserService();
UserService proxy = (UserService) new CglibProxy(userService).getProxyInstance();
proxy.report();
}
结果查看:



