JAVA动态代理cglib或jdk
cglib或jdk动态代理
Proxy代理,只把tostrng,equal,hashcode交给handler(原对象)去实现,其他的自己实现,所以调用getclass().getName()时返回$proxy0
java.lang.reflect.Proxy代理的原理,1.生成代理类。2.如果原对象设置了需要代理(如Trancational注解),则返回代理对象(即添加了增强方法的代理对象),返回的对象想要强转,只能强转成接口。
Spring AOP的底层就是通过JDK动态代理或CGLib动态代理技术 为目标Bean执行横向织入。
1.若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理。
2.若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类。
cglib不但可以接受接口,还能接受普通类。
package platformc.aoptest; import lombok.Data; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; /** * @author: CHX * @date: 2021/3/28 20:42 */ @Data public class TestFactory implements MethodInterceptor { private Object target; private MyAdvice advice = new MyAdvice(); public static void main(String[] args) { try { //通过代理获取对象 Object bean = new TestFactory().getBean("platformc.aoptest.TestFactory", "java.util.ArrayList"); System.out.println(bean.getClass().getName()); System.out.println(((ArrayList<Object>) bean).size()); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } } /** * 通过代理获取对象 * * @param proxyName 代理对象类名 * @param targetName 被代理对象类名 * @return * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException */ public Object getBean(String proxyName, String targetName) throws ClassNotFoundException, IllegalAccessException, InstantiationException { //获取代理对象(实际应用中,可更换为判断注解) Class<?> aClass = Class.forName(proxyName); Object bean = aClass.newInstance(); if (bean instanceof TestFactory) { //如果代理类是我们自定义的代理类,则开始进行方法增强。 target = Class.forName(targetName).newInstance(); //设置被代理对象 ((TestFactory) bean).setTarget(target); return ((TestFactory) bean).getProxy(); } return bean; } /** * 分为cglib代理或jdk代理。 * * @return */ public Object getProxy() { Object o; //分为cglib代理和jdk代理,本身是接口则用jdk,否则用cglib if (target.getClass().isInterface()) { o = Proxy.newProxyInstance(target.getClass().getClassLoader(), //注意此处,传入是实现的接口。 target.getClass().getInterfaces(), (proxy, method, args) -> { advice.befor(method); Object invoke = method.invoke(target, args); advice.after(method); return invoke; }); } else { //创建一个动态类对象,即增强类对象 Enhancer enhancer = new Enhancer(); //确定需要增强的类,设置为父类 enhancer.setSuperclass(target.getClass()); //确定代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法 enhancer.setCallback(this); //返回创建的代理对象 o = enhancer.create(); } return o; } /** * @param o 代理对象本身 * @param method 被代理对象方法 * @param objects 被代理对象入参 * @param methodProxy 可执行代理方法或被代理对象的方法 * @return * @throws Throwable */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { advice.befor(method); Object invoke = methodProxy.invokeSuper(o, objects); advice.after(method); return invoke; } }
执行结果