• java的动态代理如何实现


    一. JdkProxy

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

    1. 接口UserInterface.java
    1. public interface UserService {
    2. String getUserName(String userCde);
    3. }
    1. 原始实现类:UseServiceImpl.java
    1. public class UserServiceImpl implements UserSerice {
    2. @Override
    3. public String getUserName(String userCde) {
    4. System.out.println("the name of " + userCde + "is Austin");
    5. return "Austin";
    6. }
    7. }
    1. 代理类 :UserProxyFactoryBJdk.java
    1. public class UserProxyFactoryBJdk {
    2. public static UserService getUserServiceProxy(UserService origin) {
    3. UserService userService = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader()
    4. , new Class[]{UserService.class}
    5. , new InvocationHandler() { //动态代理实现类
    6. @Override
    7. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    8. System.out.println("before");
    9. Object o = method.invoke(origin, args);
    10. System.out.println("after");
    11. return o;
    12. }
    13. });
    14. return userService;
    15. }
    16. public static void main(String[] args) {
    17. UserService userService = getUserServiceProxy(new UserServiceImpl());
    18. userService.getUserName("123");
    19. }
    20. }

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

    二. Cglib动态代理

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

    1. 原始类UseServiceImpl.java
    1. public class UserServiceImpl implements UserSerice {
    2. @Override
    3. public String getUserName(String userCde) {
    4. System.out.println("the name of " + userCde + "is Austin");
    5. return "Austin";
    6. }
    7. }
    1. 代理类 :UserProxyFactoryByCglib.java
    1. public static UserServiceImpl getUserServiceProxy(UserService origin) {
    2. Enhancer enhancer = new Enhancer();
    3. // 设置debug信息
    4. System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY
    5. , "/home/aa/dev/testfile/com/austin/meta/cxf/");
    6. // 设置父类:UserServiceImpl
    7. enhancer.setSuperclass(UserServiceImpl.class);
    8. //设置代理实现逻辑
    9. enhancer.setCallback(new CglibInterCeptor() {
    10. public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    11. System.out.println("CglibInterCeptor.intercept-before");
    12. Object o = proxy.invokeSuper(obj, args);
    13. System.out.println("CglibInterCeptor.intercept-after");
    14. return o;
    15. }
    16. });
    17. UserServiceImpl userService = ((UserServiceImpl) enhancer.create());
    18. return userService;
    19. }
    20. public static void main(String[] args) {
    21. UserService userService = getUserServiceProxy(new UserServiceImpl());
    22. userService.getUserName("123");
    23. }

    1. 执行结果
      CglibInterCeptor.intercept-before
      the name of 123is Austin
      CglibInterCeptor.intercept-after

    三. Java动态编译

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

    1. 需要动态编译的类文件
    1. package com.austin.meta.dynamiccompiler;
    2. public class UserServiceImplE extends UserServiceImpl {
    3. public UserServiceImplE() {
    4. }
    5. public String getUserName(String userCde) {
    6. System.out.println("before");
    7. super.getUserName(userCde);
    8. System.out.println("after");
    9. return "Austin";
    10. }
    11. }
    1. 动态编译类
    1. public class JavaCompilerTest {
    2. private static String basePath = "";
    3. public static void main(String[] args) throws Exception{
    4. System.out.println(ClassLoader.getSystemResource(""));
    5. Class<?> userServiceImplE = compiler("UserServiceImplE");
    6. UserServiceImpl o = (UserServiceImpl)userServiceImplE.getConstructor(null).newInstance(null);
    7. o.getUserName("235");
    8. }
    9. private static Class<?> getClass(String pakcge, String className) {
    10. Class<?> clazz = null;
    11. try {
    12. clazz = Class.forName(pakcge + "." +className, true, JavaCompilerTest.class.getClassLoader());
    13. } catch (ClassNotFoundException e) {
    14. e.printStackTrace();
    15. }
    16. return clazz;
    17. }
    18. /**
    19. * 动态编译java类,并通加载到JVM
    20. */
    21. private static Class<?> compiler(String className) throws IOException {
    22. File javaSrcFile = new File(basePath+ "/" + className + ".java");
    23. JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    24. StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null);
    25. List<String> options = Arrays.asList("-d", ClassLoader.getSystemResource("").toString());
    26. JavaCompiler.CompilationTask task = compiler.getTask(null
    27. , standardFileManager, null, options, null, standardFileManager.getJavaFileObjects(javaSrcFile));
    28. Boolean isCompilerSuccess = task.call();
    29. if(!isCompilerSuccess) {
    30. return null;
    31. }
    32. Class<?> clazz = getClass("com.austin.meta.dynamiccompiler", className);
    33. return clazz;
    34. }
    35. }

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

  • 相关阅读:
    java版本+工程项目管理系统源码+项目模块功能清单+spring cloud +spring boot
    SQL创建数据库
    PD18 无法启动bootcamp,DlInitialzeLibrary failed 0xc00000bb的一个原因
    智慧能源:引领未来的能源革命
    论文学习:Graph Data Augmentation for Graph Machine Learning: A Survey
    股票交易数据接口获取股票基础信息数据的过程
    王江涛十天搞定考研词汇
    SpringCloud的nacos多项目、多环境的命名空间和分组配置
    BERT: 面向语言理解的深度双向Transformer预训练
    力扣刷题-哈希表-哈希表理论基础
  • 原文地址:https://blog.csdn.net/Lzfnemo2009/article/details/132794597