private void enhanceJPACallback(CtClass ctClass, CtMethod method, Class anno) throws Exception { if (method.hasAnnotation(anno)) { CtMethod ctMethod = CtMethod.make( format( "public void {}() {\n" + " net.csdn.jpa.context.JPAContext jpaContext = getJPAConfig().reInitJPAContext();\n" + " try {\n" + " {}();\n" + " getJPAConfig().getJPAContext().closeTx(false);\n" + " } catch (Exception e) {\n" + " getJPAConfig().getJPAContext().closeTx(true);\n" + " } finally {\n" + " getJPAConfig().setJPAContext(jpaContext);\n" + " }\n" + " }", "$_" + method.getName(), method.getName()), ctClass); ctClass.addMethod(ctMethod); AnnotationsAttribute annotationsAttribute = EnhancerHelper.getAnnotations(ctMethod); EnhancerHelper.createAnnotation(annotationsAttribute, callback_classes.get(anno)); } }
private void changeMethod(CtClass ctClass, CtMethod ctMethod) throws CannotCompileException { // basically your before-advice... ctMethod.insertBefore("System.out.println(\"started method at \" + new java.util.Date());"); // basically your after-advice... ctMethod.insertAfter("System.out.println(\"ended method at \" + new java.util.Date());"); // basically your around-advice... String methodName = ctMethod.getName(); String proxyName = methodName + "_$proxy"; CtMethod proxy = CtNewMethod.copy(ctMethod, proxyName, ctClass, null); ctMethod.setName(ctMethod.getName() + "_orig"); proxy.setBody( "{ System.out.println(\"hoot!\"); return $proceed($$);}", "this", ctMethod.getName()); proxy.setName(methodName); ctClass.addMethod(proxy); }
public T createJavassistProxy( LoadBalancer loadBalance, ConcurrentMap<String, T> map, Class ifaces) throws Exception { Class<?>[] interfaces = ifaces.getInterfaces(); if (interfaces.length == 1) { ClassPool mPool = new ClassPool(true); CtClass ctClass = mPool.get(interfaces[0].getName()); // 新建代理类 CtClass mCtc = mPool.makeClass(ifaces.getName() + "$JavassistProxy"); mCtc.setSuperclass(ctClass); for (CtMethod method : ctClass.getDeclaredMethods()) { System.out.println(method.getName()); // CtMethod m = new CtMethod(method.getReturnType(), // ,method.getParameterTypes(), mCtc); // cc.addMethod(m); // m.setBody("{ x += $1; }"); mCtc.addMethod(method); // method.setBody(""); } // mCtc.debugWriteFile("/home/liguojun"); return null; } else { return null; } }
private void preprocessMethods(CtClass cc, boolean insertLoad, boolean wrapFieldAccess) throws CannotCompileException { CtMethod[] methods = cc.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { CtMethod m = methods[i]; if (wrapFieldAccess) { m.instrument( new ExprEditor() { public void edit(FieldAccess fa) throws CannotCompileException { try { if ((fa.getField().getModifiers() & (Modifier.TRANSIENT | Modifier.STATIC)) == 0 && fa.getField().getDeclaringClass().subtypeOf(persistentInterface)) { if (fa.isWriter()) { fa.replace("{ $0.loadAndModify(); $proceed($$); }"); } // isSelfReader is my extension of JAssist, if you // use original version of JAssist comment the // branch below or replace "else if" with "else". // In first case Perst will not be able to handle // access to foreign (non-this) fields. You should use // getter/setter methods instead. // In second case access to foreign fields still will be possible, // but with significant degradation of performance and // increased code size, because in this case before ALL access // to fields of persistent capable object call of load() method // will be inserted. else if (!fa.isSelfReader()) { fa.replace("{ $0.load(); $_ = $proceed($$); }"); } } } catch (NotFoundException x) { } } }); } if (insertLoad && !"recursiveLoading".equals(m.getName()) && (m.getModifiers() & (Modifier.STATIC | Modifier.ABSTRACT)) == 0) { m.insertBefore("load();"); } } }