java 动态代理

2025-11-03 07:57:13

1、一、打开eclipse,创建一个普通java工程 dynamicAgent 具体步骤为:

    File -> New -> java Project,写好工程名,finish结束

java 动态代理

2、二、在src下创建一个Student接口,包名用默认的就行,提供三个方法来获取Student的基本信息

具体步骤为:

   鼠标右击 src -> New ->interface,写好接口名Student,finish结束

具体代码为:

package dynamicAgent;

/**

 * 封装了学生的一些基本信息,具体由StudentImpl提供实现

 * @return 姓名、性别、年龄

 */

public interface Student {

//获取学生姓名

public String getStudentName(String stuName);

//获取学生性别

public String getStudentSex(String stuSex);

//获取学生年龄

public int getStudentAge(int stuAge);

}

java 动态代理

3、三、写一个StudentImpl类来实现Student接口

具体步骤为:

   鼠标包名 -> Class ,写好类名StudentImpl,finish结束

具体代码为:

package dynamicAgent;

public class StudentImpl implements Student {

@Override

public String getStudentName(String stuName) {

return stuName;

}

@Override

public String getStudentSex(String stuSex) {

return stuSex;

}

@Override

public int getStudentAge(int stuAge) {

return stuAge;

}

}

java 动态代理

4、四、写一个Main类来运行看一下控制台信息

具体步骤为:

   鼠标包名 -> Class ,写好类名Main,finish结束

具体代码为:

package dynamicAgent;

public class Main {

public static void main(String[] args) {

Student stu = new StudentImpl();

String name = stu.getStudentName("西施");

System.out.println("我的姓名:" + name);

String sex = stu.getStudentSex("女");

System.out.println("我的性别:" + sex);

int age = stu.getStudentAge(18);

System.out.println("我的年龄:" + age);

}

}

java 动态代理

java 动态代理

5、五、重要的来了,假如需要我们写日志跟踪每个方法的开始和结束,实现如下图的显示信息,若不用动态代理,代码将会变得很分散和混乱,且需要修改的时候会变得很麻烦

java 动态代理

6、六,若不用动态代理,我们就要去修改StudentImpl,因为这个类是具体实现方法的,而我们需要日志跟踪每个方法的开始和结束,这样做也能实现上述的显示

具体代码为:

package dynamicAgent;

public class StudentImpl implements Student {

@Override

public String getStudentName(String stuName) {

System.out.println("这个方法getStudentName开始了,正在获取,请稍等...");

String name=stuName;

System.out.println("这个方法getStudentName结束了,获取完毕");

return name;

}

@Override

public String getStudentSex(String stuSex) {

System.out.println("这个方法getStudentSex开始了,正在获取,请稍等...");

String sex=stuSex;

System.out.println("这个方法getStudentSex结束了,获取完毕");

return sex;

}

@Override

public int getStudentAge(int stuAge) {

System.out.println("这个方法getStudentAge开始了,正在获取,请稍等...");

int age=stuAge;

System.out.println("这个方法getStudentAge结束了,获取完毕");

return age;

}

}

java 动态代理

7、七、这样做代码不易维护,而且工作量也变大了,怎么说呢?若是有成千上万个方法,这样做了,原有的业务方法就会急剧膨胀;而且,若要修改每条日志的显示信息,想想都会觉得很不舒服对吧。所以在没有优秀框架去解决的情况下,我们就需要去弄动态代理来解决这个问题。把StudentImpl改回原样

java 动态代理

8、八、写一个StudentProxy类来实现动态代理

具体步骤为:

   鼠标包名 -> Class ,写好类名StudentProxy,finish结束

具体代码为:

package dynamicAgent;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

public class StudentProxy {

//要代理的对象

private Student stu;

//构造器初始化要代理的对象

public StudentProxy(Student stu) {

this.stu=stu;

}

//返回代理对象

public Student getLoggingProxy(){

Student proxy=null;

ClassLoader loader=stu.getClass().getClassLoader();

Class[] interfaces=new Class[]{Student.class};

InvocationHandler handler=new InvocationHandler() {

@Override

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

String methodName=method.getName();

System.out.println("这个方法:"+ methodName +"开始运行了,正在获取,请稍等...");

Object result=null;

try {

result=method.invoke(stu, args);

} catch (NullPointerException e) {

e.printStackTrace();

}

System.out.println("这个方法:"+ methodName +"运行结束了,获取完毕");

return result;

}

};

/**

* loader: 代理对象使用的类加载器。 

* interfaces: 指定代理对象的类型. 即代理代理对象中可以有哪些方法. 

* handler: 当具体调用代理对象的方法时, 应该如何进行响应, 实际上就是调用 InvocationHandler 的 invoke 方法

*/

proxy=(Student) Proxy.newProxyInstance(loader, interfaces, handler);

return proxy;

}

}

java 动态代理

9、九、修改main方法,看运行结果是一样的

具体代码为:

package dynamicAgent;

public class Main {

public static void main(String[] args) {

Student stu = new StudentImpl();

stu=new StudentProxy(stu).getLoggingProxy();

String name=stu.getStudentName("西施");

System.out.println("姓名:"+name);

String sex=stu.getStudentSex("女");

System.out.println("性别:"+sex);

int age=stu.getStudentAge(18);

System.out.println("年龄:"+age);

}

}

java 动态代理

10、十、这样做,代码纯净多了,还易于维护,想要修改日志,只需要去StudentProxy修改两条日志显示就OK了,感觉爽了很多,若是加入spring框架,用spring的AOP,我们连StudentProxy类都不用写了,AOP直接帮我们搞定了,这就更爽了

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢