一. JdkProxy

jdkproxy动态代理必须基于接口(interface)实现

  1. 接口UserInterface.java
public interface UserService {
	String getUserName(String userCde);
}
  1. 原始实现类:UseServiceImpl.java
public class UserServiceImpl implements UserSerice {
	@Override
	public String getUserName(String userCde) {
		System.out.println("the name of " + userCde + "is Austin");
        return "Austin";
	}
}
  1. 代理类 :UserProxyFactoryBJdk.java
public class UserProxyFactoryBJdk {
	public static UserService getUserServiceProxy(UserService origin) {
        UserService userService = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader()
                , new Class[]{UserService.class}
				, new InvocationHandler() { //动态代理实现类
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("before");
                        Object o = method.invoke(origin, args);
                        System.out.println("after");
                        return o;
                    }
                });
        return userService;
    }

    public static void main(String[] args) {
        UserService userService = getUserServiceProxy(new UserServiceImpl());
        userService.getUserName("123");
    }
}

java的动态代理如何实现-LMLPHP

执行结果:
before
the name of 123is Austin
after

二. Cglib动态代理

Cglib实现动态代理与JdkProxy不同, 是通过构建继承类实现

  1. 原始类UseServiceImpl.java
public class UserServiceImpl implements UserSerice {
	@Override
	public String getUserName(String userCde) {
		System.out.println("the name of " + userCde + "is Austin");
        return "Austin";
	}
}
  1. 代理类 :UserProxyFactoryByCglib.java
public static UserServiceImpl getUserServiceProxy(UserService origin) {
        Enhancer enhancer = new Enhancer();
        // 设置debug信息
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY
                , "/home/aa/dev/testfile/com/austin/meta/cxf/");
        // 设置父类:UserServiceImpl
        enhancer.setSuperclass(UserServiceImpl.class);
        //设置代理实现逻辑
        enhancer.setCallback(new CglibInterCeptor() {
        	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("CglibInterCeptor.intercept-before");
        Object o = proxy.invokeSuper(obj, args);
        System.out.println("CglibInterCeptor.intercept-after");
        return o;
    }
        });
        UserServiceImpl userService = ((UserServiceImpl) enhancer.create());
        return userService;
    }

    public static void main(String[] args) {
        UserService userService = getUserServiceProxy(new UserServiceImpl());
        userService.getUserName("123");
    }
  1. 执行结果
    CglibInterCeptor.intercept-before
    the name of 123is Austin
    CglibInterCeptor.intercept-after

三. Java动态编译

通过JavaCompiler动态编译java源文件,并将相应字节码加载到JVM中,其编译底层通过javac -d 命令进行编译

  1. 需要动态编译的类文件
package com.austin.meta.dynamiccompiler;
public class UserServiceImplE extends UserServiceImpl {
    public UserServiceImplE() {
    }
    public String getUserName(String userCde) {
        System.out.println("before");
        super.getUserName(userCde);
        System.out.println("after");
        return "Austin";
    }
}
  1. 动态编译类
public class JavaCompilerTest {
	private static String basePath = "";
	public static void main(String[] args) throws Exception{
        System.out.println(ClassLoader.getSystemResource(""));
        Class<?> userServiceImplE = compiler("UserServiceImplE");
        UserServiceImpl o = (UserServiceImpl)userServiceImplE.getConstructor(null).newInstance(null);
        o.getUserName("235");

    }
  private static Class<?> getClass(String pakcge, String className) {
        Class<?> clazz = null;
        try {
            clazz = Class.forName(pakcge + "." +className, true, JavaCompilerTest.class.getClassLoader());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return clazz;
    }
   /**
   * 动态编译java类,并通加载到JVM
   */
private static Class<?> compiler(String className) throws IOException {
        File javaSrcFile = new File(basePath+ "/" + className + ".java");
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null);
        List<String> options = Arrays.asList("-d", ClassLoader.getSystemResource("").toString());
        JavaCompiler.CompilationTask task = compiler.getTask(null
                , standardFileManager, null, options, null, standardFileManager.getJavaFileObjects(javaSrcFile));
        Boolean isCompilerSuccess = task.call();
        if(!isCompilerSuccess) {
            return null;
        }
        Class<?> clazz = getClass("com.austin.meta.dynamiccompiler", className);
        return clazz;
    }
}

  1. 执行结果
    before
    the name of 235is Austin
    after

09-11 16:01