Cglib代理不要求目标对象实现一个接口
1) 在内存中动态构建子类,注意代理的类不能为final,否则报错java.lang.IllegalArgumentException
2) 目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法
添加maven依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
1.真实角色
public class TeacherDao {
public void teach() {
System.out.println("TeacherDao teach");
}
}
2.代理角色
拦截器里放一个过滤器链,用户在过滤器里拦截多重调用。spring aop 就是使用这样的方式。
public class ProxyFactory {
// 维护一个目标对象
private Object target;
// 构造器传入一个被代理对象
public ProxyFactory(Object target) {
this.target = target;
}
// 返回一个代理对象,是target对象的代理对象
public Object getProxyInstance() {
// 1.创建一个工具类
Enhancer enhancer = new Enhancer();
// 2.设置父类
enhancer.setSuperclass(target.getClass());
// 3.设置回调函数
enhancer.setCallback(new MyMethodInterceptor());
// 2. 创建子类对象,即代理对象
return enhancer.create();
}
class MyMethodInterceptor implements MethodInterceptor {
// 重写intercept方法,会调用目标对象的方法
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("cglib proxy begin...");
List<Point> points = Arrays.asList(new Point1(), new Point2());
Object result = new Chain(target, method, args, points).proceed();
// Object result = method.invoke(target, args);
System.out.println("cglib proxy end...");
return result;
}
}
interface Point {
Object invoke(Chain chain) throws Throwable;
}
public class Chain {
private Object target;
private Method method;
private Object[] arguments;
private List<Point> points;
private int index = -1;
public Chain(Object target, Method method, Object[] arguments, List<Point> points) {
this.target = target;
this.method = method;
this.arguments = arguments;
this.points = points;
}
public Object proceed() throws Throwable {
if (++index == points.size()) {
return method.invoke(target, arguments);
}
Point point = points.get(index);
return point.invoke(this);
}
}
public class Point1 implements Point {
@Override
public Object invoke(Chain chain) throws Throwable {
System.out.println("point 1 before");
Object result = chain.proceed();
System.out.println("point 1 after");
return result;
}
}
public class Point2 implements Point {
@Override
public Object invoke(Chain chain) throws Throwable {
System.out.println("point 2 before");
Object result = chain.proceed();
System.out.println("point 2 after");
return result;
}
}
}
3.测试
@Test
public void testCglib() {
TeacherDao teacherDao = new TeacherDao();
TeacherDao proxyInstance = (TeacherDao) new ProxyFactory(teacherDao).getProxyInstance();
proxyInstance.teach();
}