动态代理模式
- 简介:通过反射创建出代理对象,再通过代理对象调用原方法,可以在这个过程中对目标方法进行增强,aop就是基于这个原理。在spring中动态代理有两种方式,jdk动态代理,和cglib动态代理。如果目标实现了接口,优先使用jdk动态代理。否则使用cglib动态代理,cglib动态代理通过在运行时动态生成目标类的子类,从而实现对目标方法的增强。
- jdk动态代理
package com.dhr.study.springAop.jdk;
public interface Rent {
void house();
}
package com.dhr.study.springAop.jdk;
public class RentImpl implements Rent {
@Override
public void house() {
System.out.println("租房子");
}
}
- 创建代理对象
通过Proxy.newProxyInstance()方法生成代理的对象
package com.dhr.study.springAop.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TestMain {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
RentImpl rent = new RentImpl();
InvocationHandler invocationHandler = (proxy, method, args1) -> {
System.out.println("前面");
Object invoke = method.invoke(rent, args1);
System.out.println("后面");
return invoke;
};
Rent proxy = (Rent)Proxy.newProxyInstance(rent.getClass().getClassLoader(), rent.getClass().getInterfaces(), invocationHandler);
proxy.house();
}
}
- 执行结果
- cglib动态代理
通过Enhancer的create方法创建出代理对象
package com.dhr.study.springAop.cglib;
import com.dhr.study.springAop.jdk.Rent;
import com.dhr.study.springAop.jdk.RentImpl;
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 TestCglib {
public static void main(String[] args) {
RentImpl rent = new RentImpl();
Enhancer enhancer = new Enhancer();
enhancer.setClassLoader(rent.getClass().getClassLoader());
enhancer.setSuperclass(rent.getClass());
MethodInterceptor methodInterceptor = new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("前面");
Object invoke = method.invoke(rent, objects);
System.out.println("后面");
return invoke;
}
};
enhancer.setCallback(methodInterceptor);
Rent o = (Rent)enhancer.create();
o.house();
}
}
- 执行结果