Proxy提供用于创建动态代理类和代理对象的静态方法,它也是所有动态代理类的父类。如果我们在程序中为一个或多个接口动态地生成实现类,就可以使用Proxy来创建动态代理类;如果需要为一个或多个接口动态的创建实例,也可以使用Proxy来创建动态代理实例。

Proxy提供了如下两个方法来创建动态代理类和动态代理类:

(1)、static Class<?>  getProxyClass(ClassLoader loader,Class<?> ...interfaces) : 创建一个动态代理类所对应的Class对象,该代理类将实现interfaces所指定的多个接口。第一个ClassLoader指定生成动态代理类的类加载器。

(2)、static Object newProxyInstance(ClassLoader loader,Class<?>  interfaces, InvocationHandler  h) :直接创建一个动态代理对象,该代理对象的实现类实现了interfaces指定的系列接口,执行代理对象的每个方法时都会被替换成执行          InvocationHandler对象的invoke方法。

实际上,即使采用第一种方式获取了一个动态代理类之后,当程序需要通过该代理类来创建对象时一样需要传入一个InvocationHandler对象。也就是说,系统生成的每个代理对象都有一个与之关联的InvocationHandler对象。

下面是AOP动态代理的实现:

在方法前后加入一写通用方法,比如项目中的日志记录。

Dog.java

package com.reflect.proxy;

public interface Dog {
public void info();
public void run();
}

GunDog.java

package com.reflect.proxy;

public class GunDog implements Dog {

	@Override
public void info() {
System.out.println("我是一只猎狗");
} @Override
public void run() {
System.out.println("我奔跑迅速");
} }

DogUtil.java

package com.reflect.proxy;

public class DogUtil {

	public void method1(){
System.out.println("=====模拟第1个通用方法======");
} public void method2(){
System.out.println("=====模拟第2个通用方法======");
} }

借助于Proxy和InvocationHandler就可以实现:当程序调用info()方法和run()方法时,系统就可以“自动” 将method1()和method2() 两个通用方法插入info()和run()犯法

package com.reflect.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler { //需要被代理的对象
private Object target; public void setTarget(Object target){
this.target=target;
} //指定动态代理的所有方法时,都会替换成执行如下的invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
DogUtil du=new DogUtil(); //执行DogUtil中的method1
du.method1();
//以target为主掉来执行method方法
Object result=method.invoke(target, args);
System.out.println(result);
//执行DogUtil中的Method2
du.method2();
return result;
} }

为指定的target生成代理类.

package com.reflect.proxy;

import java.lang.reflect.Proxy;

public class MyProxyFactory {

	//为指定target生成动态代理对象
public static Object getProxy(Object target){
MyInvocationHandler handler=new MyInvocationHandler();
//为MyInvotationHandler设置target对象
handler.setTarget(target);
//创建并返回一个动态代理
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
}
}

测试类

package com.reflect.proxy;

public class Test {

	public static void main(String[] args) {

		//创建一个原始的GunDog对象,作为target
Dog target=new GunDog();
//以指定的target创建动态代理
Dog dog=(Dog) MyProxyFactory.getProxy(target);
dog.info();
dog.run();
}
}

输出:

=====模拟第1个通用方法======
我是一只猎狗
=====模拟第2个通用方法====== =====模拟第1个通用方法======
我奔跑迅速
=====模拟第2个通用方法======

最新文章

  1. 【手记】注意BinaryWriter写string的小坑——会在string前加上长度前缀length-prefixed
  2. [转]SQL 常用函数及示例
  3. javascript模拟继承
  4. Windows Azure初体验
  5. 也谈谈规范JS代码的几个注意点
  6. HTML5自学笔记[ 3 ]表单验证反馈
  7. iOS之GCD的局部解析
  8. 精通ASP.Net MVC 3 框架(第三版)学习笔记
  9. php文本操作方法集合
  10. Win7 32位系统下Java开发环境的安装及配置
  11. curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set in
  12. POJ 1511 Invitation Cards 正反SPFA
  13. NodeMCU之旅(二):断线自动重连,闪烁连接状态
  14. Spring MVC的配置与DispatcherServlet的分析
  15. mysql 与 oracle 的连表update
  16. vue项目做seo优化(prerender-spa-plugin vue-meta-info)
  17. RPM 包的构建 - SPEC 基础知识
  18. 在 Android Studio 上调试数据库 ( SQLite ) (转)
  19. 《Python 网络爬虫权威指南》 分享 pdf下载
  20. JavaScript中函数和构造函数的区别

热门文章

  1. Linux中MySQL忽略表中字段大小写
  2. Bootstrap3 栅格系统-简介
  3. Apache ActiveMQ实战(1)-基本安装配置与消息类型
  4. 初识Vulkan
  5. Android Studio精彩案例(二)《仿微信动态点击底部tab切换Fragment》
  6. Web自动化框架LazyUI使用手册(7)--浏览器常用操作API
  7. 【完整的App项目】颖火虫笔记
  8. Java异常处理-----非运行时异常(受检异常)
  9. RxJava操作符(03-变换操作)
  10. Xcode无法安装基于ruby的插件问题的解决