- 浏览: 19218 次
- 性别:
- 来自: 上海
文章分类
最新评论
Spring AOP 的底层实现是Java Proxy和CGLib,而CGLib的底层实现是ASM.
本示例直接从ASM实现轻量型AOP框架
1.XSD配置文件约束:
XML实现例子
2.配置文件容器及常量:
3.配置文件解析:
4.AOP实现,包括方法前拦截,方法返回拦截,异常拦截等:
5.提供WebLogic服务器的实现
本示例直接从ASM实现轻量型AOP框架
1.XSD配置文件约束:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema targetNamespace="http://www.youisoft.org/aaop" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.youisoft.org/aaop" elementFormDefault="qualified" version="1.0"> <xs:simpleType name="match"> <xs:restriction base="xs:string"> <xs:enumeration value="dynamic"/> <xs:enumeration value="exception"/> <xs:enumeration value="none"/> <xs:enumeration value="parameter"/> </xs:restriction> </xs:simpleType> <xs:complexType name="Descriptor"> <xs:choice> <xs:element name="args" type="Args" minOccurs="0" maxOccurs="1"/> <xs:element name="pattern" type="xs:string" minOccurs="0" maxOccurs="1"/> </xs:choice> </xs:complexType> <xs:complexType name="Args"> <xs:sequence> <xs:element name="arg" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="ret" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="exp" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:complexType name="Config"> <xs:sequence> <xs:element name="service" type="Service" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> <xs:element name="config" type="Config"/> <xs:complexType name="Adapter"> <xs:sequence/> <xs:attribute name="class" use="optional" type="xs:string"/> <xs:attribute name="name" use="optional" type="xs:string"/> </xs:complexType> <xs:complexType name="Service"> <xs:sequence minOccurs="0"> <xs:element name="adapter" type="Adapter" minOccurs="0" maxOccurs="1"/> <xs:element name="component" type="Component" minOccurs="1" maxOccurs="1"/> <xs:element name="method" type="Method" minOccurs="1" maxOccurs="1"/> </xs:sequence> <xs:attribute name="class" use="optional" type="xs:string"/> <xs:attribute name="match" use="optional" default="none" type="match"/> <xs:attribute name="name" use="optional" type="xs:string"/> <xs:attribute name="static" use="optional" default="false" type="xs:boolean"/> <xs:attribute name="style" use="optional" default="return" type="Style"/> </xs:complexType> <xs:complexType name="Component"> <xs:sequence> <xs:element name="method" type="Method" minOccurs="0" maxOccurs="1"/> </xs:sequence> <xs:attribute name="class" use="optional" type="xs:string"/> <xs:attribute name="name" use="optional" type="xs:string"/> </xs:complexType> <xs:simpleType name="Style"> <xs:restriction base="xs:string"> <xs:enumeration value="after"/> <xs:enumeration value="before"/> <xs:enumeration value="return"/> <xs:enumeration value="throw"/> </xs:restriction> </xs:simpleType> <xs:complexType name="Method"> <xs:sequence> <xs:element name="descriptor" type="Descriptor" minOccurs="0" maxOccurs="1"/> </xs:sequence> <xs:attribute name="match" use="optional" default="none" type="match"/> <xs:attribute name="name" use="optional" type="xs:string"/> </xs:complexType> </xs:schema>
XML实现例子
<?xml version="1.0" encoding="UTF-8"?> <config xmlns="http://www.youisoft.org/aaop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.youisoft.org/aaop xsd/aaop-1.0.xsd "> <service class="org.youisoft.sample.SampleService" name="sampleService" style="return"> <component class="org.youisoft.sample.SampleComponent" name="sampleComponent"> <method name="invoke"></method> </component> <method name="sample"> <descriptor> <args> <arg>org.youisoft.sample.Request</arg> <ret>org.youisoft.sample.Response</ret></args></descriptor> </method> </service> </config>
2.配置文件容器及常量:
package org.youisoft.config; /** * * @author janly * */ public class Configs{ private java.util.List list=new java.util.ArrayList(); /** * * @param config */ public void setConfig(Config config){ list.add(config); } /** * @return the configs */ public Config[] getConfigs() { return (Config[])list.toArray(new Config[]{}); } }
package org.youisoft; /** * * @author janly * */ public interface AopStyle{ public final static String STYLE_BEFORE="before"; public final static String STYLE_AFTER="after"; public final static String STYLE_THROW="throw"; public final static String STYLE_RETURN="return"; public final static String MATCH_NONE="none"; public final static String MATCH_DYNAMIC="dynamic"; public final static String MATCH_PARAMETER="parameter"; public final static String MATCH_EXCEPTION="exception"; /** * * @param style */ public void setStyle(String style); }
3.配置文件解析:
package org.youisoft.config; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * * @author janly * */ public class XmlConfig { private final static String SERVICE="/config/service"; private final static String METHODADAPTER="/config/service/adapter"; private final static String SERVICEMETHOD="/config/service/method"; private final static String SERVICEPATTERN="/config/service/method/descriptor/pattern"; private final static String SERVICEARG="/config/service/method/descriptor/args/arg"; private final static String SERVICERET="/config/service/method/descriptor/args/ret"; private final static String SERVICEEXP="/config/service/method/descriptor/args/exp"; private final static String COMPONENT="/config/service/component"; private final static String COMPONENTMETHOD="/config/service/component/method"; private final static String COMPONENTPATTERN="/config/service/component/method/descriptor/pattern"; private final static String COMPONENTARG="/config/service/component/method/descriptor/args/arg"; private final static String COMPONENTRET="/config/service/component/method/descriptor/args/ret"; private final static String COMPONENTEXP="/config/service/component/method/descriptor/args/exp"; public static Configs parserXml(org.xml.sax.InputSource inputSource){ final Configs configs=new Configs(); SAXParserFactory saxFactory=SAXParserFactory.newInstance(); saxFactory.setNamespaceAware(true); try { javax.xml.parsers.SAXParser saxParser=saxFactory.newSAXParser(); saxParser.parse(inputSource, new DefaultHandler(){ private PathStack ps=new PathStack(); private Config config; /* (non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int) */ public void characters(char[] ch, int start, int length) throws SAXException { if(SERVICEPATTERN.equals(ps.getPath())){ config.getServiceMethod().setPattern(new String(ch,start,length)); } if(COMPONENTPATTERN.equals(ps.getPath())){ config.getComponentMethod().setPattern(new String(ch,start,length)); } if(SERVICEARG.equals(ps.getPath())){ config.getServiceMethod().addArg(new String(ch,start,length)); } if(SERVICERET.equals(ps.getPath())){ config.getServiceMethod().addRet(new String(ch,start,length)); } if(SERVICEEXP.equals(ps.getPath())){ config.getServiceMethod().addExp(new String(ch,start,length)); } if(COMPONENTARG.equals(ps.getPath())){ config.getComponentMethod().addArg(new String(ch,start,length)); } if(COMPONENTRET.equals(ps.getPath())){ config.getComponentMethod().addRet(new String(ch,start,length)); } if(COMPONENTEXP.equals(ps.getPath())){ config.getComponentMethod().addExp(new String(ch,start,length)); } } /* (non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String) */ public void endElement(String uri, String localName, String name) throws SAXException { if(SERVICE.equals(ps.getPath())){ configs.setConfig(config); } ps.pop(); } /* (non-Javadoc) * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) */ public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { ps.push(localName); if(SERVICE.equals(ps.getPath())){ config=new Config(); config.setServiceClassName(attributes.getValue("class")); config.setServiceName(attributes.getValue("name")); if(attributes.getValue("style")!=null) config.setStyle(attributes.getValue("style")); if(attributes.getValue("match")!=null) config.setMatch(attributes.getValue("match")); if(attributes.getValue("static")!=null) config.setStaticInvoke(new Boolean(attributes.getValue("static")).booleanValue()); } if(METHODADAPTER.equals(ps.getPath())){ config.setAdapterClassName(attributes.getValue("class")); config.setAdapterName(attributes.getValue("name")); } if(SERVICEMETHOD.equals(ps.getPath())){ config.getServiceMethod().setMethodName(attributes.getValue("name")); config.getServiceMethod().setMatch(attributes.getValue("match")); } if(COMPONENT.equals(ps.getPath())){ config.setComponentClassName(attributes.getValue("class")); config.setComponentName(attributes.getValue("name")); } if(COMPONENTMETHOD.equals(ps.getPath())){ config.getComponentMethod().setMethodName(attributes.getValue("name")); config.getComponentMethod().setMatch(attributes.getValue("match")); } } /** * * @author janly * */ class PathStack extends java.util.Stack{ /** * */ private static final long serialVersionUID = 1L; private java.util.Stack stack=new java.util.Stack(); public String getPath(){ java.lang.StringBuffer sb=new java.lang.StringBuffer(); for(int i=0;i<stack.size();i++){ sb.append("/"); sb.append(stack.get(i).toString()); } return sb.toString(); } /* (non-Javadoc) * @see java.util.Stack#empty() */ public boolean empty() { // TODO Auto-generated method stub return stack.empty(); } /* (non-Javadoc) * @see java.util.Stack#peek() */ public synchronized Object peek() { // TODO Auto-generated method stub return stack.peek(); } /* (non-Javadoc) * @see java.util.Stack#pop() */ public synchronized Object pop() { // TODO Auto-generated method stub return stack.pop(); } /* (non-Javadoc) * @see java.util.Stack#push(java.lang.Object) */ public Object push(Object arg0) { // TODO Auto-generated method stub return stack.push(arg0); } /* (non-Javadoc) * @see java.util.Stack#search(java.lang.Object) */ public synchronized int search(Object o) { // TODO Auto-generated method stub return stack.search(o); } } } ); } catch (Exception e) { e.printStackTrace(); } return configs; } }
4.AOP实现,包括方法前拦截,方法返回拦截,异常拦截等:
package org.youisoft.config; import java.io.IOException; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.MethodAdapter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import org.youisoft.AopStyle; /** * * @author janly * */ public class Config { private String serviceName; private String serviceClassName; private String componentClassName; private String componentName; private String adapterClassName; private String adapterName; private boolean staticInvoke; private String style=AopStyle.STYLE_RETURN; private String match=AopStyle.MATCH_NONE; private final Method serviceMethod=new Method(); private final Method componentMethod=new Method(); private boolean catchValue=false; /** * initialise the default method name,method arguments,method return,method exception of component. */ public void initServiceComponent(){ //default method name if(this.getComponentMethod().getMethodName()==null) this.getComponentMethod().setMethodName(this.getServiceMethod().getMethodName()); if(this.componentMethod.getDescriptor()==null){ for(java.util.Iterator it=this.getServiceMethod().getArgs().iterator();it.hasNext();){ this.getComponentMethod().addArg(it.next().toString()); } for(java.util.Iterator it=this.getServiceMethod().getRets().iterator();it.hasNext();){ this.getComponentMethod().addRet(it.next().toString()); } } if(this.componentMethod.getExceptions().length==0){ for(java.util.Iterator it=this.getServiceMethod().getExps().iterator();it.hasNext();){ this.getComponentMethod().addExp(it.next().toString()); } } } /** * * @param data * @return */ public byte[] config(byte[] data){ org.objectweb.asm.ClassReader cr = new org.objectweb.asm.ClassReader(data); return config(cr); } /** * * @return */ public byte[] config(){ java.io.InputStream is=this.getClass().getClassLoader().getResourceAsStream(Config.this.getServiceClassName().concat(".class")); org.objectweb.asm.ClassReader cr=null; try { cr = new org.objectweb.asm.ClassReader(is); } catch (IOException e) { e.printStackTrace(); } return config(cr); } /** * the main method of AOP. * first: method of service in configuration match the destination method. * second: method of component in configuration match the service method. * @return */ private byte[] config(org.objectweb.asm.ClassReader cr){ try{ org.objectweb.asm.ClassWriter cw=new org.objectweb.asm.ClassWriter(cr,ClassWriter.COMPUTE_MAXS); org.objectweb.asm.ClassAdapter ca=new org.objectweb.asm.ClassAdapter(cw){ public MethodVisitor visitMethod(int arg0, String arg1, String arg2,String arg3, String[] arg4) { MethodVisitor mv=super.visitMethod(arg0, arg1, arg2, arg3, arg4); if(mv!=null){ boolean match=false; if(arg1.equals(serviceMethod.getMethodName())){ if(serviceMethod.getMatch().equals(AopStyle.MATCH_NONE)|| serviceMethod.getMatch().equals(AopStyle.MATCH_DYNAMIC) ){ serviceMethod.setPattern(arg2); serviceMethod.clearExps(); for(int i=0;arg4!=null&&i<arg4.length;i++){ serviceMethod.addExp(arg4[i]); } match=true; }else if(serviceMethod.getMatch().equals(AopStyle.MATCH_PARAMETER)&& serviceMethod.getDescriptor().equals(arg2)){ serviceMethod.clearExps(); for(int i=0;arg4!=null&&i<arg4.length;i++){ serviceMethod.addExp(arg4[i]); } match=true; }else if(serviceMethod.getMatch().equals(AopStyle.MATCH_EXCEPTION)&& serviceMethod.getDescriptor().equals(arg2)){ if(arg4!=null&&serviceMethod.getExceptions().length==arg4.length){ match=true; for(int i=0;i<arg4.length;i++){ if(!arg4[i].equals(serviceMethod.getExceptions()[i])) match=false; } } } } if(match){ if(Config.this.getAdapterClassName()!=null){ try { Class clazz=Class.forName(Config.this.getAdapterClassName()); if(MethodAdapter.class.isAssignableFrom(clazz)){ java.lang.reflect.Constructor con=clazz.getConstructor(new Class[]{MethodVisitor.class}); mv=(MethodAdapter)con.newInstance(new Object[]{mv}); if(AopStyle.class.isAssignableFrom(clazz)){ ((AopStyle)mv).setStyle(Config.this.getStyle()); } } } catch (Exception e) { e.printStackTrace(); } }else{ if(Config.this.getStyle().equals(AopStyle.STYLE_BEFORE)){ mv=new org.objectweb.asm.MethodAdapter(mv){ /* (non-Javadoc) * @see org.objectweb.asm.MethodAdapter#visitCode() */ public void visitCode() { if(getServiceComponentMatch()){ Type[] argType=Type.getArgumentTypes(Config.this.getServiceMethod().getDescriptor()); if(Config.this.isStaticInvoke()){ for(int i=1;i<=argType.length;i++){ super.visitVarInsn(argType[i-1].getOpcode(Opcodes.ILOAD), i); } super.visitMethodInsn(Opcodes.INVOKESTATIC,Config.this.getComponentClassName(), Config.this.getComponentMethod().getMethodName(),Config.this.getComponentMethod().getDescriptor()); }else{ super.visitTypeInsn(Opcodes.NEW, Config.this.getComponentClassName()); super.visitInsn(Opcodes.DUP); super.visitMethodInsn(Opcodes.INVOKESPECIAL,Config.this.getComponentClassName(), "<init>", "()V"); for(int i=1;i<=argType.length;i++){ super.visitVarInsn(argType[i-1].getOpcode(Opcodes.ILOAD), i); } super.visitMethodInsn(Opcodes.INVOKEVIRTUAL,Config.this.getComponentClassName(), Config.this.getComponentMethod().getMethodName(),Config.this.getComponentMethod().getDescriptor()); } super.visitInsn(Opcodes.POP); } super.visitCode(); } }; } if(Config.this.getStyle().equals(AopStyle.STYLE_AFTER)){ mv=new org.objectweb.asm.MethodAdapter(mv){ /* (non-Javadoc) * @see org.objectweb.asm.MethodAdapter#visitInsn(int) */ public void visitInsn(int opcode) { if(opcode>=Opcodes.IRETURN&&opcode<=Opcodes.RETURN){ if(getServiceComponentMatch()){ Type[] argType=Type.getArgumentTypes(Config.this.getServiceMethod().getDescriptor()); if(Config.this.isStaticInvoke()){ for(int i=1;i<=argType.length;i++){ super.visitVarInsn(argType[i-1].getOpcode(Opcodes.ILOAD), i); } super.visitMethodInsn(Opcodes.INVOKESTATIC,Config.this.getComponentClassName(), Config.this.getComponentMethod().getMethodName(),Config.this.getComponentMethod().getDescriptor()); }else{ super.visitTypeInsn(Opcodes.NEW, Config.this.getComponentClassName()); super.visitInsn(Opcodes.DUP); super.visitMethodInsn(Opcodes.INVOKESPECIAL,Config.this.getComponentClassName(), "<init>", "()V"); for(int i=1;i<=argType.length;i++){ super.visitVarInsn(argType[i-1].getOpcode(Opcodes.ILOAD), i); } super.visitMethodInsn(Opcodes.INVOKEVIRTUAL,Config.this.getComponentClassName(), Config.this.getComponentMethod().getMethodName(),Config.this.getComponentMethod().getDescriptor()); } super.visitInsn(Opcodes.POP); } } super.visitInsn(opcode); } }; } if(Config.this.getStyle().equals(AopStyle.STYLE_THROW)){ mv=new org.objectweb.asm.MethodAdapter(mv){ private int idx=0; private java.util.List lList=new java.util.ArrayList(); /* (non-Javadoc) * @see org.objectweb.asm.MethodAdapter#visitLabel(org.objectweb.asm.Label) */ public void visitLabel(Label arg0) { super.visitLabel(arg0); if(lList.contains(arg0)&&getServiceComponentMatch()){ Type[] argType=Type.getArgumentTypes(Config.this.getServiceMethod().getDescriptor()); super.visitVarInsn(Opcodes.ASTORE,idx+1); if(Config.this.isStaticInvoke()){ for(int i=1;i<=argType.length;i++){ super.visitVarInsn(argType[i-1].getOpcode(Opcodes.ILOAD), i); } if(catchValue) super.visitVarInsn(Opcodes.ALOAD,idx+1); super.visitMethodInsn(Opcodes.INVOKESTATIC,Config.this.getComponentClassName(), Config.this.getComponentMethod().getMethodName(),Config.this.getComponentMethod().getDescriptor()); }else{ super.visitTypeInsn(Opcodes.NEW, Config.this.getComponentClassName()); super.visitInsn(Opcodes.DUP); super.visitMethodInsn(Opcodes.INVOKESPECIAL,Config.this.getComponentClassName(), "<init>", "()V"); for(int i=1;i<=argType.length;i++){ super.visitVarInsn(argType[i-1].getOpcode(Opcodes.ILOAD), i); } if(catchValue) super.visitVarInsn(Opcodes.ALOAD,idx+1); super.visitMethodInsn(Opcodes.INVOKEVIRTUAL,Config.this.getComponentClassName(), Config.this.getComponentMethod().getMethodName(),Config.this.getComponentMethod().getDescriptor()); } super.visitInsn(Opcodes.POP); super.visitVarInsn(Opcodes.ALOAD,idx+1); } } /* (non-Javadoc) * @see org.objectweb.asm.MethodAdapter#visitTryCatchBlock(org.objectweb.asm.Label, org.objectweb.asm.Label, org.objectweb.asm.Label, java.lang.String) */ public void visitTryCatchBlock(Label arg0, Label arg1,Label arg2, String arg3) { if(arg2!=null) this.lList.add(arg2); super.visitTryCatchBlock(arg0, arg1, arg2, arg3); } /* (non-Javadoc) * @see org.objectweb.asm.MethodAdapter#visitVarInsn(int, int) */ public void visitVarInsn(int arg0, int arg1) { if(arg0>=54&&arg0<=86){ if(arg1>idx) idx=arg1; } super.visitVarInsn(arg0, arg1); } }; } if(Config.this.getStyle().equals(AopStyle.STYLE_RETURN)){ mv=new org.objectweb.asm.MethodAdapter(mv){ private int idx=0; /* (non-Javadoc) * @see org.objectweb.asm.MethodAdapter#visitVarInsn(int, int) */ public void visitVarInsn(int arg0, int arg1) { if(arg0>=54&&arg0<=86){ if(arg1>idx) idx=arg1; } super.visitVarInsn(arg0, arg1); } public void visitInsn(int opcode) { if(opcode>=Opcodes.IRETURN&&opcode<=Opcodes.RETURN){ if(getServiceComponentMatch()){ Type[] argType=Type.getArgumentTypes(Config.this.getServiceMethod().getDescriptor()); Type retType=Type.getReturnType(Config.this.getServiceMethod().getDescriptor()); if(catchValue) { super.visitVarInsn(retType.getOpcode(Opcodes.ISTORE),idx+1); }else{ super.visitInsn(Opcodes.POP); } if(Config.this.isStaticInvoke()){ for(int i=1;i<=argType.length;i++){ super.visitVarInsn(argType[i-1].getOpcode(Opcodes.ILOAD), i); } if(catchValue) super.visitVarInsn(retType.getOpcode(Opcodes.ILOAD), idx+1); super.visitMethodInsn(Opcodes.INVOKESTATIC,Config.this.getComponentClassName(), Config.this.getComponentMethod().getMethodName(),Config.this.getComponentMethod().getDescriptor()); }else{ super.visitTypeInsn(Opcodes.NEW, Config.this.getComponentClassName()); super.visitInsn(Opcodes.DUP); super.visitMethodInsn(Opcodes.INVOKESPECIAL,Config.this.getComponentClassName(), "<init>", "()V"); for(int i=1;i<=argType.length;i++){ super.visitVarInsn(argType[i-1].getOpcode(Opcodes.ILOAD), i); } if(catchValue) super.visitVarInsn(retType.getOpcode(Opcodes.ILOAD), idx+1); super.visitMethodInsn(Opcodes.INVOKEVIRTUAL,Config.this.getComponentClassName(), Config.this.getComponentMethod().getMethodName(),Config.this.getComponentMethod().getDescriptor()); } } } super.visitInsn(opcode); } }; } } } } return mv; } }; cr.accept(ca, org.objectweb.asm.ClassReader.SKIP_DEBUG); return cw.toByteArray(); }catch(Exception e){ e.printStackTrace(); return null; } } private boolean getServiceComponentMatch(){ this.initServiceComponent(); boolean match=false; if(this.getComponentMethod().getMatch().equals(AopStyle.MATCH_NONE)|| this.getComponentMethod().getMatch().equals(AopStyle.MATCH_PARAMETER)){ if(this.getComponentMethod().getDescriptor().equals(this.getServiceMethod().getDescriptor())){ match=true; } return match; } if(this.getComponentMethod().getMatch().equals(AopStyle.MATCH_DYNAMIC)){ Type[] sargType=Type.getArgumentTypes(Config.this.getServiceMethod().getDescriptor()); Type sretType=Type.getReturnType(Config.this.getServiceMethod().getDescriptor()); Type[] cArgType=Type.getArgumentTypes(Config.this.getComponentMethod().getDescriptor()); if(sargType.length==cArgType.length-1){ if(sretType.toString().equals(cArgType[cArgType.length-1].toString())|| Type.getDescriptor(java.lang.Throwable.class).equals(cArgType[cArgType.length-1].toString()) ){ match=true; catchValue=true; } } return match; } if(this.getComponentMethod().getMatch().equals(AopStyle.MATCH_EXCEPTION)){ if(this.getComponentMethod().getDescriptor().equals(this.getServiceMethod().getDescriptor())){ if(this.getComponentMethod().getExceptions().length==this.getServiceMethod().getExceptions().length){ match=true; for(int i=0;i<this.getComponentMethod().getExceptions().length;i++){ if(!this.getComponentMethod().getExceptions()[i].equals(this.getServiceMethod().getExceptions()[i])) match=false; } } } return match; } return match; } /** * * @param str * @param begin * @param end * @return */ private static String substringBetween(String str,String begin,String end){ int a=str.indexOf(begin); int b=str.lastIndexOf(end); return str.substring(a, b); } /** * * @param str * @param begin * @return */ private static String substringBefore(String str,String begin){ int a=str.indexOf(begin); return str.substring(0,a); } /** * * @param str * @param end * @return */ private static String substringAfter(String str,String end){ int a=str.indexOf(end); return str.substring(a+1); } /** * * @param s * @param sb */ public static void converToSimplePattern(String s,java.lang.StringBuffer sb){ if(s.startsWith("(")) { converToSimplePattern(substringBetween(s, "(", ")"),sb); return; } if(s.startsWith("[")) { converToSimplePattern(substringAfter(s,"["),sb); return; } if(s.startsWith("L")){ sb.append("L"); converToSimplePattern(substringAfter(s,";"),sb); return; } if(s!=null&&s.length()>0){ sb.append(s.substring(0,1)); converToSimplePattern(s.substring(1),sb); return; } } /** * * @param s * @return */ public static String converToPattern(String s){ java.lang.StringBuffer sb=new java.lang.StringBuffer(""); if(s.equals("void")) sb.append(Type.getDescriptor(void.class)); if(s.equals("boolean")) sb.append(Type.getDescriptor(boolean.class)); if(s.equals("int")) sb.append(Type.getDescriptor(int.class)); if(s.equals("char")) sb.append(Type.getDescriptor(char.class)); if(s.equals("byte")) sb.append(Type.getDescriptor(byte.class)); if(s.equals("short")) sb.append(Type.getDescriptor(short.class)); if(s.equals("float")) sb.append(Type.getDescriptor(float.class)); if(s.equals("long")) sb.append(Type.getDescriptor(long.class)); if(s.equals("double")) sb.append(Type.getDescriptor(double.class)); if(s.equals("boolean[]")) sb.append(Type.getDescriptor(boolean[].class)); if(s.equals("int[]")) sb.append(Type.getDescriptor(int[].class)); if(s.equals("char[]")) sb.append(Type.getDescriptor(char[].class)); if(s.equals("byte[]")) sb.append(Type.getDescriptor(byte[].class)); if(s.equals("short[]")) sb.append(Type.getDescriptor(short[].class)); if(s.equals("float[]")) sb.append(Type.getDescriptor(float[].class)); if(s.equals("long[]")) sb.append(Type.getDescriptor(long[].class)); if(s.equals("double[]")) sb.append(Type.getDescriptor(double[].class)); if(s.equals("boolean[][]")) sb.append(Type.getDescriptor(boolean[][].class)); if(s.equals("int[][]")) sb.append(Type.getDescriptor(int[][].class)); if(s.equals("char[][]")) sb.append(Type.getDescriptor(char[][].class)); if(s.equals("byte[][]")) sb.append(Type.getDescriptor(byte[][].class)); if(s.equals("short[][]")) sb.append(Type.getDescriptor(short[][].class)); if(s.equals("float[][]")) sb.append(Type.getDescriptor(float[][].class)); if(s.equals("long[][]")) sb.append(Type.getDescriptor(long[][].class)); if(s.equals("double[][]")) sb.append(Type.getDescriptor(double[][].class)); if(!sb.toString().equals("")) return sb.toString(); if(s.endsWith("[][]")) { sb.append("[[L"+sb.append(substringBefore(s, "[][]"))); }else if(s.endsWith("[]")) { sb.append("[L"+sb.append(substringBefore(s, "[]"))); }else{ sb.append("L"+s); } sb.append(";"); return sb.toString(); } /** * @return the serviceName */ public String getServiceName() { return serviceName; } /** * @param serviceName the serviceName to set */ public void setServiceName(String serviceName) { this.serviceName = serviceName; } /** * @return the serviceClassName */ public String getServiceClassName() { return serviceClassName; } /** * @param serviceClassName the serviceClassName to set */ public void setServiceClassName(String serviceClassName) { if(serviceClassName!=null) serviceClassName=serviceClassName.replace('.', '/'); this.serviceClassName = serviceClassName; } /** * @return the componentClassName */ public String getComponentClassName() { return componentClassName; } /** * @param componentClassName the componentClassName to set */ public void setComponentClassName(String componentClassName) { if(componentClassName!=null) componentClassName=componentClassName.replace('.', '/'); this.componentClassName = componentClassName; } /** * @return the componentName */ public String getComponentName() { return componentName; } /** * @param componentName the componentName to set */ public void setComponentName(String componentName) { this.componentName = componentName; } /** * @return the style */ public String getStyle() { return style; } /** * @param style the style to set */ public void setStyle(String style) { this.style = style; } /** * @return the adapterClassName */ public String getAdapterClassName() { return adapterClassName; } /** * @param adapterClassName the adapterClassName to set */ public void setAdapterClassName(String adapterClassName) { this.adapterClassName = adapterClassName; } /** * @return the adapterName */ public String getAdapterName() { return adapterName; } /** * @param adapterName the adapterName to set */ public void setAdapterName(String adapterName) { this.adapterName = adapterName; } /** * @return the match */ public String getMatch() { return match; } /** * @param match the match to set */ public void setMatch(String match) { this.match = match; } /** * @return the staticInvoke */ public boolean isStaticInvoke() { return staticInvoke; } /** * @param staticInvoke the staticInvoke to set */ public void setStaticInvoke(boolean staticInvoke) { this.staticInvoke = staticInvoke; } /** * @return the serviceMethod */ public Method getServiceMethod() { return serviceMethod; } /** * @return the componentMethod */ public Method getComponentMethod() { return componentMethod; } /** * * @author janly * */ class Method{ private String methodName; private String pattern; private String match; private final java.util.List args=new java.util.ArrayList(); private final java.util.List rets=new java.util.ArrayList(); private final java.util.List exps=new java.util.ArrayList(); public void clearExps(){ this.exps.clear(); } private String convertArgsToPattern(){ if(methodName==null) return null; if(this.rets.isEmpty()) return null; java.lang.StringBuffer sb=new java.lang.StringBuffer("("); for(java.util.Iterator it=this.args.iterator();it.hasNext();){ sb.append(Config.converToPattern(it.next().toString())); } sb.append(")"); for(java.util.Iterator it=this.rets.iterator();it.hasNext();){ sb.append(Config.converToPattern(it.next().toString())); } return sb.toString(); } public String[] getExceptions(){ return (String[])this.exps.toArray(new String[]{}); } boolean addArg(String arg){ return args.add(arg.replace('.', '/')); } boolean addRet(String ret){ return rets.add(ret.replace('.', '/')); } boolean addExp(String exp){ return exps.add(exp.replace('.', '/')); } /** * @return the pattern */ public String getPattern() { return pattern; } /** * @param pattern the pattern to set */ public void setPattern(String pattern) { this.pattern = pattern; this.args.clear(); this.rets.clear(); Type[] argsType=Type.getArgumentTypes(pattern); Type retsType=Type.getReturnType(pattern); for(int i=0;i<argsType.length;i++){ this.args.add(argsType[i].getClassName()); } this.rets.add(retsType.getClassName()); } /** * @return the methodName */ public String getMethodName() { return methodName; } /** * @param methodName the methodName to set */ public void setMethodName(String methodName) { this.methodName = methodName; } /** * @return the descriptor */ public String getDescriptor() { if(this.pattern!=null) return this.pattern; return this.convertArgsToPattern(); } /** * @return the args */ public java.util.List getArgs() { return args; } /** * @return the rets */ public java.util.List getRets() { return rets; } /** * @return the exps */ public java.util.List getExps() { return exps; } /** * @return the match */ public String getMatch() { if(this.match==null) return Config.this.getMatch(); return match; } /** * @param match the match to set */ public void setMatch(String match) { this.match = match; } } }
5.提供WebLogic服务器的实现
/** * */ package org.youisoft.oracle; import java.util.Hashtable; import org.youisoft.config.Config; import org.youisoft.config.Configs; import org.youisoft.config.XmlConfig; import weblogic.utils.classloaders.ClassPreProcessor; /** * @author janly * */ public class ServiceClassPreProcessor implements ClassPreProcessor { private class KeyListMap{ private java.util.Map innerMap=new java.util.HashMap(); /* (non-Javadoc) * @see java.util.HashMap#put(java.lang.Object, java.lang.Object) */ public Object put(Object arg0, Object arg1) { if(this.innerMap.get(arg0)==null){ java.util.List list=new java.util.ArrayList(); list.add(arg1); this.innerMap.put(arg0,list); }else{ ((java.util.List)this.innerMap.get(arg0)).add(arg1); } return arg1; } /* (non-Javadoc) * @see java.util.HashMap#get(java.lang.Object) */ public Object get(Object key) { return this.innerMap.get(key); } } public final static String XMLCONFIG="youisoft.service.config"; //-Dweblogic.classloader.preprocessor=org.youisoft.oracle.ServiceClassPreProcessor private KeyListMap serviceMap=new KeyListMap(); /* (non-Javadoc) * @see weblogic.utils.classloaders.ClassPreProcessor#initialize(java.util.Hashtable) */ public void initialize(Hashtable arg0) { String configFileName=null; if(arg0!=null&&arg0.get(XMLCONFIG)!=null){ configFileName=arg0.get(XMLCONFIG).toString(); } if(System.getProperty(XMLCONFIG)!=null){ configFileName=System.getProperty(XMLCONFIG); } try{ java.io.FileInputStream fis=new java.io.FileInputStream(configFileName); org.xml.sax.InputSource inputSource=new org.xml.sax.InputSource(fis); Configs obj=(Configs)XmlConfig.parserXml(inputSource); for(int i=0;obj.getConfigs()!=null&&i<obj.getConfigs().length;i++){ this.serviceMap.put(obj.getConfigs()[i].getServiceClassName().replace('/', '.'), obj.getConfigs()[i]); } }catch(Exception e){ e.printStackTrace(); } } /* (non-Javadoc) * @see weblogic.utils.classloaders.ClassPreProcessor#preProcess(java.lang.String, byte[]) */ public byte[] preProcess(String arg0, byte[] arg1) { if(this.serviceMap.get(arg0)!=null){ try{ java.util.List list=(java.util.List)this.serviceMap.get(arg0); for(java.util.Iterator it=list.iterator();it.hasNext();){ Config config=(Config)it.next(); arg1=config.config(arg1); } }catch(java.lang.Throwable t){ } } return arg1; } }
发表评论
-
负载均衡池LVS-Keepalived-Haproxy总结
2013-05-12 21:31 769负载均衡池架构设计,日访问量2000万以上 -
Maven父项目,结合Maven根项目
2013-05-12 20:55 958<project xmlns="http:/ ... -
Maven根项目
2013-05-12 20:54 911<project xmlns="http:/ ... -
maven-setting文件,结合Maven根项目,父项目
2013-05-12 21:34 1480<?xml version="1.0&qu ... -
OAuth 2.0 基础建模
2011-04-13 20:36 1371这几天一直在做OAuth 2.0的压力测试,虽然过程中遇 ...
相关推荐
本文将详细介绍一种轻量级的Java字节码操控框架——ASM 3.0,并探讨其如何帮助实现AOP。 #### 什么是ASM? ASM是一个用于动态生成或增强现有Java类的字节码操控框架。它可以被用来直接修改`.class`文件,也可以在...
ASM库是一个轻量级的Java字节码操控和分析框架,常用于动态代理、代码生成以及AOP实现。本篇文章将深入探讨如何使用ASM库来实现函数监听,特别是如何在函数执行前拦截并改变其参数值。 首先,我们需要理解ASM库的...
**ASM** 是一个轻量级的字节码处理库,它允许用户在运行时动态生成类和接口,或者修改已有的类。ASM.jar包含了ASM库的所有核心类,这些类可以解析和生成Java字节码,从而实现对Java类的低级别操作。 **ASM-Commons*...
ASM是一个轻量级的Java字节码操控和分析框架,而CGLIB是一个强大的代码生成库,它在许多情况下作为Spring框架的依赖用于AOP(面向切面编程)。 首先,我们来看ASM库。ASM-2.2.3.jar、asm-commons-2.2.3.jar和asm-...
开发者可以利用ASM来实现诸如AOP框架、代码生成工具、性能分析器等功能。 总的来说,ASM BYTECODE OUTLINE插件是Android Studio中一个强大的辅助工具,它结合了ASM库的强大功能,提供了直观的字节码查看界面,有助...
ASM是一个轻量级的Java字节码操控和分析框架,它可以直接生成和读取Java类的字节码。ASM提供了一种低级别的接口,允许开发者创建、修改和分析类或对象。在Spring框架中,ASM主要用于AOP(面向切面编程)的实现,例如...
可能还有cglib-nodep.jar,这是一个轻量级的字节码库,用于生成代理类。还可能包括asm.jar,这是一个用于读写Java字节码的库,Spring AOP在使用CGLIB代理时可能会用到。 总之,AOP提供了一种有效处理系统中横切关注...
此外,社区还提供了许多基于ASM的开源项目,如CGLIB(一个代码生成库,用于创建子类和动态代理)和Aspectran(一个基于AOP的轻量级服务框架)。 总之,ASM-3.1.jar是一个强大的工具,它允许开发者深入到Java字节码...
Spring框架是Java开发中最常用的轻量级框架之一,它的核心特性包括依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP)。本压缩包中的资源着重于Spring框架的AOP部分,这是一...
8. **common-logging**:这是一个轻量级的日志抽象层,允许开发者选择不同的日志实现,如Log4j、java.util.logging或commons-logging自身。Spring使用它来记录框架内部的信息,方便开发者调整日志级别和选择合适的...
3. **轻量级**:ASM库的体积相对较小,且无需额外的运行时依赖,易于集成到项目中。 然而,ASM也有一定的学习曲线,因为它涉及到对Java字节码和JVM内部机制的深入理解。但是,一旦掌握了基本用法,ASM就能够成为...
ASM是一个轻量级的库,提供了对Java字节码的低级别访问。它能够直接操作字节码,从而可以用于创建、加载或修改类。ASM提供了两种主要的API:ClassWriter用于生成字节码,而ClassReader则用于解析已存在的字节码。 ...
它是一个轻量级的Java字节码操控和分析框架,可以直接生成和修改Java类文件的字节码。在cglib中,asm库用于动态生成字节码,帮助我们创建目标类的子类。ASM提供了一套API,可以直接操作字节码,实现对类的增强,如...
6. **性能**:由于其轻量级的设计,ASM在处理字节码时具有较高的性能,尤其在大量生成或分析类时,效率表现优秀。 使用ASM时,你需要了解基本的字节码概念,如常量池、操作码、栈映射表等,并熟悉ASM提供的类和接口...
- ASM是一个轻量级的字节码操作和分析框架,它可以直接生成和修改Java类的字节码。 - 在CGLIB中,ASM负责生成和修改字节码,创建目标类的子类,以及在子类中插入额外的代码,实现方法拦截。 4. **CGLIB的优缺点**...
同时,由于ASM Tree库是一个轻量级的库,它的性能表现良好,非常适合在内存有限或者对性能要求高的环境中使用。 为了有效地使用ASM Tree库1.5.3.jar,开发者需要了解Java字节码的相关知识,包括类文件结构、操作码...
4. **轻量级**:ASM的设计目标之一是小巧且高效,这使得它在资源有限的环境中也能良好工作。 接下来,我们关注"asm-xml-20041228.180559.jar"。这个文件名暗示了ASM库的一个版本可能被扩展或集成了XML处理能力。XML...
例如,Spring AOP框架就利用ASM来生成代理类以实现切面逻辑。同时,由于ASM的性能优秀且小巧,它也是许多轻量级库的首选。 综上所述,"asm-1.5.2.jar.zip"是一个包含ASM 1.5.2版本的JAR文件和许可证信息的压缩包,...
7. `asm*.jar` (例如:asm-7.1.jar): 这些是ASM库的版本,ASM是一个轻量级的Java字节码操控和分析框架,Spring使用它来实现动态代理和织入切面。 8. `cglib-nodep.jar`: 有时,Spring会使用CGLIB作为动态代理的实现...
XWork框架提供了一种轻量级的、基于Action的模型,支持拦截器和类型转换,使得业务处理更加灵活和模块化。它的Action接口和ActionSupport类是开发者编写业务逻辑的入口,而Interceptor(拦截器)则允许在Action执行...