JAVA AOP编程之动态代理技术

简介:  java中的代理是什么呢? 比如说我们用到一个类A ,我们往常的方法就是直接使用这个类A  ,这样在大型的软件开发中有很大的局限性、 。    我们对于使用的类A的修改只能通过对源文件硬编码的修改, 代理就很好的突破了这个瓶颈。

 java中的代理是什么呢?

比如说我们用到一个类A ,我们往常的方法就是直接使用这个类A  ,这样在大型的软件开发中有很大的局限性、 。    我们对于使用的类A的修改只能通过对源文件硬编码的修改,

代理就很好的突破了这个瓶颈。

在代理中我们可以定义一个类B,这个类B有个特点 就是和类A有着实现同样的接口 ,我们在类B中间接的调用了 类A,  我们也可以向这个代理的类插入一些通告消息类 。

着在开发框架中经常用到 。

在JAVA中用于动态生成代理类的类 就是  java.lang.reflect.Proxy  这个类 具体的使用 可以去 看看有关于JDK的文档 。   

在AOP的程序设计中,InvocationHandler 这个类是作为代理类对于target类的间接调用者 ,所有的被代理类都是通过 这个InvocationHandler这个类来进行调用的 。

我们在对这些步骤进行操作的时候 只需要把实现过程封装起来  把 需要代理的类 作为Object传递进去 那么就可以实现 代理的通用化  ,于是一个小java框架就产生了 。

在使用的过程用 涉及到匿名内部类 ,这里提到 在匿名内部类中调用外部的对象 需要 吧外面的对象 声明为 final 。。。。 这是java的语法 为了是保证数据的安全性。。

StirngBuffer是一个线程安全的类,继承了String在多线程中用到  。

如果只涉及到 单线程那么 就用 StringBuilder这个类 效率会提高很多。。

关于代理的结构图如下:

 

下面我写一个例子来实现动态代理 :

package me.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
import java.lang.reflect.TypeVariable;
public class MyProxy
{    
 public static void main(String []args) throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException
 {
 Class  clazzProxy=Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class) ;        //利用Proxy类产生一份代理类的字节码
 //Create a  Dynamic  Class  by  using  Proxy  
 Constructor  constructors[]=clazzProxy.getConstructors()  ;   //获得代理类的构造方法数组 反射原理
 Method []methods=clazzProxy.getMethods()  ;     //获得代理类的方法
 System.out.println("Constructor List:"); 
 for(Constructor con:constructors) 
 {    
  String cons=con.getName() ;
  StringBuilder conBuilder=new StringBuilder(cons) ;
  Class []types = con.getParameterTypes()  ;
  conBuilder.append('(')  ;
     if(types.length!=0&&types!=null)
     {
      for(Class type:types)
      {
       conBuilder.append(type.getName())  ;
       conBuilder.append(',')  ;
      }
      conBuilder.deleteCharAt(conBuilder.lastIndexOf(",")) ;
     }  
    
  conBuilder.append(')') ;
   
     System.out.println(conBuilder);
   
 }
 System.out.println("Methoid list:");  
 for(Method med:methods) 
 {   
  String cons=med.getName() ;
  StringBuilder conBuilder=new StringBuilder(cons) ;
  Class []types = med.getParameterTypes()  ;
  conBuilder.append('(')  ;
     if(types.length!=0&&types!=null)
     {
      for(Class type:types)
      {
       conBuilder.append(type.getName())  ;
       conBuilder.append(',')  ;
      }
      conBuilder.deleteCharAt(conBuilder.lastIndexOf(",")) ;
     }  
    
  conBuilder.append(')') ;
   
     System.out.println(conBuilder);
   
 }
 
 /////////////////////////////////////////////////////////////这里是代理类的实现部分
 class  MyInvocationHandler implements InvocationHandler  
 {

  @Override
  public Object invoke(Object proxy, Method method, Object[] args)                   
    throws Throwable {
   // TODO Auto-generated method stub
   return null;
  }
  
 }
 Collection cn1=(Collection)constructors[0].newInstance((new MyInvocationHandler()))   ;    //生成一个代理类的对象 这个对象实现了 Collection接口
 System.out.println(cn1.toString());
 /*************************************************************************************/   
 Collection cn2=(Collection)constructors[0].newInstance(new InvocationHandler(){

  @Override
  public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable {
   // TODO Auto-generated method stub
   return null;
  }
 })  ;
 /***************************************************************************************/
  final ArrayList list=new ArrayList() ;
    Advice adv=new MyAdvice() ;  //通告类 对象
  Collection cn3 = getProxy(list, adv);
  
   cn3.add("xiaowei")  ; //会调用 对于代理类的操作会调用InvocationHandler的invoke方法  进行调用目标类  ,调用方法如同反射 机制
   cn3.add("man")  ;
   cn3.add("软件技术")  ;
   System.out.println("包含"+cn3.size()+"个元素!")  ;
   for(Object obj:cn3)
   {
    System.out.println(obj.toString());
   }
 }

 private static Collection getProxy(final Object list ,final Advice advice) {
  Collection cn3=(Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(),
    new Class[]{Collection.class},
    new InvocationHandler()
          
    /* @Override
     public Object invoke(Object proxy, Method method, Object[] args)  //代理类在执行每一个被代理类的方法的时候 就会调用这个invoke方法 并且传递Method对象 我们就可以动态的调用目的类的方法
       throws Throwable {
       // ArrayList list=new ArrayList() ;    //必须作为一个成员来实现 否则 每次进行插入操纵那么调用的都是一个新的对象
       Long beginTime=System.currentTimeMillis()  ;
      Object returnVal= method.invoke(list, args);  //Invoke the Method 
       Long endTime=System.currentTimeMillis()  ; 
       System.out.println("Runtime="+(endTime-beginTime));   
       return  returnVal; 
     }*/  
   
    @Override
   public Object invoke(Object proxy, Method method, Object[] args)
     throws Throwable {
     // ArrayList list=new ArrayList() ;    //必须作为一个成员来实现 否则 每次进行插入操纵那么调用的都是一个新的对象
    
    advice.beginRun(method) ;  //内部类调用外部的对象的时候 需要使用 final声明 
    Object returnVal= method.invoke(list, args);  //Invoke the Method     执行代理传递过来的执行方法 
    advice.afterRun(method)  ;
    
     return  returnVal;   
   }
   
  }
    );
  return cn3;
 }
}

 

 //////////////////////////////////////////////////////////////////////////通告接口 和实现类

 package me.test;

import java.lang.reflect.Method;

public interface Advice

 public void beginRun(Method method) ;
 public void afterRun(Method method) ;

}
 

 

package me.test;

import java.lang.reflect.Method;

public class MyAdvice  implements Advice{
   
 long  beginTime   ;
 @Override
 public void beginRun(Method  method ) {
  
   beginTime=System.currentTimeMillis() ; 
 }

 @Override
 public void afterRun(Method  method) {
   
  long endTime=System.currentTimeMillis()   ;
  System.out.println(method.getName()+"运行了"+(endTime-beginTime)+"ms!");
  
 } 
 

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

目录
相关文章
|
9月前
|
Java
如何在Java中进行多线程编程
Java多线程编程常用方式包括:继承Thread类、实现Runnable接口、Callable接口(可返回结果)及使用线程池。推荐线程池以提升性能,避免频繁创建线程。结合同步与通信机制,可有效管理并发任务。
324 6
|
9月前
|
IDE Java 编译器
java编程最基础学习
Java入门需掌握:环境搭建、基础语法、面向对象、数组集合与异常处理。通过实践编写简单程序,逐步深入学习,打牢编程基础。
441 1
|
10月前
|
SQL Java 数据库
2025 年 Java 从零基础小白到编程高手的详细学习路线攻略
2025年Java学习路线涵盖基础语法、面向对象、数据库、JavaWeb、Spring全家桶、分布式、云原生与高并发技术,结合实战项目与源码分析,助力零基础学员系统掌握Java开发技能,从入门到精通,全面提升竞争力,顺利进阶编程高手。
1375 2
|
10月前
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
817 1
|
9月前
|
安全 前端开发 Java
从反射到方法句柄:深入探索Java动态编程的终极解决方案
从反射到方法句柄,Java 动态编程不断演进。方法句柄以强类型、低开销、易优化的特性,解决反射性能差、类型弱、安全性低等问题,结合 `invokedynamic` 成为支撑 Lambda 与动态语言的终极方案。
337 0
|
10月前
|
Java 开发者
Java并发编程:CountDownLatch实战解析
Java并发编程:CountDownLatch实战解析
621 100
|
9月前
|
监控 Java Spring
AOP 切面编程
AOP(面向切面编程)通过动态代理在不修改源码的前提下,对方法进行增强。核心概念包括连接点、通知、切入点、切面和目标对象。常用于日志记录、权限校验、性能监控等场景,结合Spring AOP与@Aspect、@Pointcut等注解,实现灵活的横切逻辑管理。
2093 6
AOP 切面编程
|
9月前
|
XML Java 数据格式
《深入理解Spring》:AOP面向切面编程深度解析
Spring AOP通过代理模式实现面向切面编程,将日志、事务等横切关注点与业务逻辑分离。支持注解、XML和编程式配置,提供五种通知类型及丰富切点表达式,助力构建高内聚、低耦合的可维护系统。
|
Java API 数据安全/隐私保护
探索Java动态代理的奥秘:JDK vs CGLIB
动态代理是一种在 运行时动态生成代理类的技术,无需手动编写代理类代码。它通过拦截目标方法的调用,实现对核心逻辑的 无侵入式增强(如日志、事务、权限控制等)。
532 0
探索Java动态代理的奥秘:JDK vs CGLIB
|
设计模式 Java 程序员
java动态代理(JDK和cglib)
java动态代理(JDK和cglib)
164 0