您的位置:首页 > 编程语言 > Java开发

代理模式之动态代理(java实现)

2016-08-20 16:22 489 查看
代理模式之动态代理(java实现)
    代理模式,即Proxy Pattern,java常用设计模式之一,定义:对其他对象提供一种代理以控制对这个对象的访问。而动态代理是一种在系统运行时动态创建需要被代理的类并对其进行代理。spring框架的AOP(面向切面)实现原理就是动态代理。

    下面是采用java实现的一种方式。需要对方法的调用前后做一些操作,如写日志等信息。

package com.steadyjack.proxyClass;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Calendar;
import java.util.GregorianCalendar;

//代理:为其它对象提供一种代理以实现对这种对象的控制访问:不直接访问实际的真实类的方法 -- 运行时动态代理:系统在运行时动态创建代理类
//可以为被代理的方法被调用前后添加一些信息:比如日志,调用结果
public class TestProxy {
public static void main(String[] args) {

//编译时invocationHandler代理的目标类为 接口AbstractDao的对象,但运行时因为new UserDao()指向了实际的类,所以代理的是UserDao类
AbstractDao userDao=new UserDao();
//传入的userDao其实就是CommonHandler类中的目标类target--这个就是需要被代理的
InvocationHandler handler=new CommonHandler(userDao);
AbstractDao realUserDao=(AbstractDao) Proxy.newProxyInstance(
userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), handler);
realUserDao.queryByName("steadjack");

}
}

//被代理类所实现的接口
interface AbstractDao{
void queryByName(String userName);
}

//实际的被代理类
class UserDao implements AbstractDao{

@Override
public void queryByName(String userName) {
if ("steadjack".equalsIgnoreCase(userName)) {
System.out.println("查询到姓名为: "+userName+" 的信息");
}else{
System.out.println("查询不到相应信息");
}
}

}

//代理类
class CommonHandler implements InvocationHandler{
private Object target;

public CommonHandler() {
super();
}

public CommonHandler(Object target) {
super();
this.target = target;
}

//代理类实际需要做的事:最后返回的是运行时被代理的对象
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
beforeInvoke();
Object result=method.invoke(target, args);
afterInvoke();
return result;
}

private Calendar calendar;

//调用之前:写日志
private void beforeInvoke(){
calendar=new GregorianCalendar();
int hour=calendar.get(Calendar.HOUR_OF_DAY);
int minute=calendar.get(Calendar.MINUTE);
int second=calendar.get(Calendar.SECOND);
String time=hour+":"+minute+":"+second;
System.out.println("调用时间: "+time);
}

//调用之后:返回结果
private void afterInvoke(){
System.out.println("调用成功");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息