动态代理在Spring中的应用
class $Proxy0 extends Proxy implements IDao
package com.tian.proxy; import com.sun.jndi.toolkit.url.UrlUtil; import javax.tools.JavaCompiler; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import java.io.*; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; public class ProxyUtil { public static Object newInstance(Object target){ Object proxy=null; Class targetInf = target.getClass().getInterfaces()[0]; Method methods[] =targetInf.getDeclaredMethods(); String line="\n"; String tab ="\t"; String infName = targetInf.getSimpleName(); String content =""; String packageContent = "package com.tian;"+line; String importContent = "import "+targetInf.getName()+";"+line; String clazzFirstLineContent = "public class $Proxy implements "+infName+"{"+line; String filedContent =tab+"private "+infName+" target;"+line; String constructorContent =tab+"public $Proxy ("+infName+" target){" +line +tab+tab+"this.target =target;" +line+tab+"}"+line; String methodContent = ""; for (Method method : methods) { String returnTypeName = method.getReturnType().getSimpleName(); String methodName =method.getName(); // Sting.class String.class Class args[] = method.getParameterTypes(); String argsContent = ""; String paramsContent=""; int flag =0; for (Class arg : args) { String temp = arg.getSimpleName(); //String //String p0,Sting p1, argsContent+=temp+" p"+flag+","; paramsContent+="p"+flag+","; flag++; } if (argsContent.length()>0){ argsContent=argsContent.substring(0,argsContent.lastIndexOf(",")-1); paramsContent=paramsContent.substring(0,paramsContent.lastIndexOf(",")-1); } methodContent+=tab+"public "+returnTypeName+" "+methodName+"("+argsContent+") {"+line +tab+tab+"System.out.println(\"log\");"+line +tab+tab+"target."+methodName+"("+paramsContent+");"+line +tab+"}"+line; } content=packageContent+importContent+clazzFirstLineContent+filedContent+constructorContent+methodContent+"}"; File file =new File("d:\\com\\tian\\$Proxy.java"); try { if (!file.exists()) { file.createNewFile(); } FileWriter fw = new FileWriter(file); fw.write(content); fw.flush(); fw.close(); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null); Iterable units = fileMgr.getJavaFileObjects(file); JavaCompiler.CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units); t.call(); fileMgr.close(); URL[] urls = new URL[]{new URL("file:D:\\\\")}; URLClassLoader urlClassLoader = new URLClassLoader(urls); Class clazz = urlClassLoader.loadClass("com.tian.$Proxy"); Constructor constructor = clazz.getConstructor(targetInf); proxy = constructor.newInstance(target); }catch (Exception e){ e.printStackTrace(); } return proxy; } } IDao proxy = (IDao) ProxyUtil.newInstance(new
@Configuration @ComponentScan("com.tian.*") public class AppConfig { @Bean public UserDaoImpl1 userDaoImpl1(){ return new UserDaoImpl1(); } @Bean public UserDaoImpl2 userDaoImp2(){ userDaoImpl1(); return new UserDaoImpl2(); } }
public class UserDaoImpl1 { public UserDaoImpl1() { System.out.println("UserDaoImpl1 init......"); } public void query() { System.out.println("UserDaoImpl1 query......."); } } public class UserDaoImpl2 { public UserDaoImpl2() { System.out.println("UserDaoImpl2 init......"); } public void query() { System.out.println("UserDaoImpl2 query......"); }
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
public class MyEnhancerCallBack implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("cglib proxy......."); return methodProxy.invokeSuper(o, objects); } }
//可以查看cglib生成的class System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "G:\\demo"); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(UserDaoImpl1.class); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setCallback(new MyEnhancerCallBack()); UserDaoImpl1 userDaoImpl1 =(UserDaoImpl1) enhancer.create(); userDaoImpl1.query();
可以把生成class拷贝到idea中
//其实就是把代理的对象作为父类 public class UserDaoImpl1$$EnhancerBySpringCGLIB$$a779f942 extends UserDaoImpl1 implements Factory { final void CGLIB$query$0() { super.query(); } public final void query() { //通过这个进行回调增强 MethodInterceptor var10000 = this.CGLIB$CALLBACK_0; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_0; } if (var10000 != null) { var10000.intercept(this, CGLIB$query$0$Method, CGLIB$emptyArgs, CGLIB$query$0$Proxy); } else { super.query(); } } }