package com.suning.dynamic_proxy.javaagent.service;
import java.util.LinkedList;
import java.util.List;
/**
* @Author 18011618
* @Description 模拟数据插入服务
* @Date 10:45 2018/6/21
* @Modify By
*/
public class InsertService {
/**
* 模拟数据插入
* @param num
*/
public void insert2(int num){
Listlist = new LinkedList<>();
for (int i =0;i;i++){
list.add(i);
}
}
public void insert1(int num){
Listlist = new LinkedList<>();
for (int i =0;i;i++){
list.add(i);
}
}
public void insert3(int num){
Listlist = new LinkedList<>();
for (int i =0;i;i++){
list.add(i);
}
}
}
删除服务:
package com.suning.dynamic_proxy.javaagent.service;
import java.util.List;
/**
* @Author 18011618
* @Description 模拟数据删除的方法
* @Date 10:45 2018/6/21
* @Modify By
*/
public class DeleteService {
public void delete(Listlist){
for (int i=0;i;i++){
list.remove(i);
}
}
}
ok,接下来就是要编写javaagent的相关实现:
定义agent的入口
package com.suning.dynamic_proxy.javaagent;
import java.lang.instrument.Instrumentation;
/**
* agent的入口类
*/
public class TimeMonitorAgent {
/**
* @Author 18011618
* @Description
* @Date 10:51 2018/6/21
* @Modify By
*/
public class ServiceTest {
public static void main(String[] args) {
//插入服务
InsertService insertService = new InsertService();
//删除服务
DeleteService deleteService = new DeleteService();
System.out.println("....begnin insert....");
insertService.insert1(1003440);
insertService.insert2(2000000);
insertService.insert3(30003203);
System.out.println(".....end insert.....");
List list = new LinkedList<>();
for (int i =0;i<29988440;i++){
list.add(i);
}
System.out.println(".....begin delete......");
deleteService.delete(list);
System.out.println("......end delete........");
}
}
package com.suning.dynamic_proxy.javaagent.patter;
import com.suning.dynamic_proxy.javaagent.TimeMonitorTransformer;
import java.lang.instrument.Instrumentation;
/**
* Created by jack on 2018/6/19.
*/
public class TimeMonitorPatterAgent {
public static void premain(String agentArgs, Instrumentation inst) {
inst.addTransformer(new PatternTransformer());
}
}
定义transformer:
package com.suning.dynamic_proxy.javaagent.patter;
import javassist.CtClass;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
/**
* Created by jack on 2018/6/19.
*
*/
public class PatternTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader, String className, Class> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
PatternMatcher matcher = new Perl5Matcher();
PatternCompiler compiler = new Perl5Compiler();
//指定的业务类String interceptorClass ="com.service.InsertService";
//指定的方法String interceptorMethod = "insert1";
try {
if (matcher.matches(className,compiler.compile(interceptorClass))){
ByteCode byteCode = new ByteCode();
CtClass ctClass = byteCode.modifyByteCode(interceptorClass, interceptorMethod);
return ctClass.toBytecode();
}
}
catch (Exception e){
e.printStackTrace();
}
return null;
}
}
修改字节码的实现:
package com.suning.dynamic_proxy.javaagent.patter;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
/**
* Created by jack on 2018/6/19.
* 修改拦截类的方法的字节码
*/
public class ByteCode {
public CtClass modifyByteCode(String className,String method)throws Exception{
ClassPool classPool = ClassPool.getDefault();
CtClass ctClass = classPool.get(className);
CtMethod oldMethod = ctClass.getDeclaredMethod(method);
String oldMethodName = oldMethod.getName();
String newName = oldMethodName + "$impl";
oldMethod.setName(newName);
CtMethod newMethod = CtNewMethod.copy(oldMethod, oldMethodName, ctClass, null);
StringBuffer sb = new StringBuffer();
sb.append("{");
sb.append("\nSystem.out.println(\"start to modify bytecode\");\n");
sb.append("long start = System.currentTimeMillis();\n");
sb.append(newName+"($$);\n");
sb.append("System.out.println(\"call method"+oldMethodName+"took\"+(System.currentTimeMillis()-start))");
sb.append("}");
newMethod.setBody(sb.toString());
ctClass.addMethod(newMethod);
return ctClass;
}
}
// 多态, 在JAVA中是这样用的, 其实在PHP当中可以自然消除, 因为参数是动态的, 你传什么过来都可以, 不限制类型, 直接调用类的方法
abstract class Tiger {
public abstract function climb();
}
class XTiger extends Tiger {
public function climb()
jQuery.extend({
handleError: function( s, xhr, status, e ) {
// If a local callback was specified, fire it
if ( s.error ) {
s.error.call( s.context || s, xhr, status, e );
}
always 总是
rice 水稻,米饭
before 在...之前
live 生活,居住
usual 通常的
early 早的
begin 开始
month 月份
year 年
last 最后的
east 东方的
high 高的
far 远的
window 窗户
world 世界
than 比...更
最近使用mybatis.3.1.0时无意中碰到一个问题:
The errors below were detected when validating the file "mybatis-3-mapper.dtd" via the file "account-mapper.xml". In most cases these errors can be d