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

java原生动态代理实现demo

2014-08-27 11:14 405 查看
这只是一个demo试验,理论性的只是较少;

1,建立数据bean:User.java

/**
* User.java
* Created at 2014年8月27日
* Created by mengfanyuan
* Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
*/
package com.mfy.test.proxy.bean;

/**
* <p>
* ClassName: User
*</p>
* <p>
* Description: TODO
* </p>
* <p>
* Author: mengfanyuan
* Email:kalvenmeng@163.com
* </p>
* <p>
* Date: 2014年8月27日
* </p>
*/
public class User {
private Integer id; // 用户Id
private String userName; //用户名
private String passWord; //密码

public User() {
super();
}

public User(Integer id, String userName, String passWord) {
super();
this.id = id;
this.userName = userName;
this.passWord = passWord;
}

public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
}

2,建服务层接口(目标类必须实现接口):IPersonService.java

/**
* IPersonService.java
* Created at 2014年8月27日
* Created by mengfanyuan
* Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
*/
package com.mfy.test.proxy.service;

import com.mfy.test.proxy.bean.User;

/**
* <p>
* ClassName: IPersonService
*</p>
* <p>
* Description: TODO
* </p>
* <p>
* Author: mengfanyuan
* Email:kalvenmeng@163.com
* </p>
* <p>
* Date: 2014年8月27日
* </p>
*/
public interface IUserService {
void save(User user);
void update(User user);
void delete(Integer id);
}<strong>
</strong>
3,服务层实现类:UserServiceImp.java

/**
* UserServiceImp.java
* Created at 2014年8月27日
* Created by mengfanyuan
* Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
*/
package com.mfy.test.proxy.service.imp;

import com.mfy.test.proxy.bean.User;
import com.mfy.test.proxy.service.IUserService;

/**
* <p>
* ClassName: UserServiceImp
*</p>
* <p>
* Description: TODO
* </p>
* <p>
* Author: mengfanyuan
* Email:kalvenmeng@163.com
* </p>
* <p>
* Date: 2014年8月27日
* </p>
*/
public class UserServiceImp implements IUserService {

@Override
public void save(User user) {
// TODO Auto-generated method stub
System.out.println("新增用户:" + user.getUserName());
}

@Override
public void update(User user) {
// TODO Auto-generated method stub
System.out.println("更新用户:" + user.getUserName());
}

@Override
public void delete(Integer id) {
// TODO Auto-generated method stub
System.out.println("删除用户Id:" + id);
}

}
4,目标方法拦截处理实现类:ProxyHandle.java

/**
* ProxyHandle.java
* Created at 2014年8月27日
* Created by mengfanyuan
* Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
*/
package com.mfy.test.proxy.handle;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
* <p>
* ClassName: ProxyHandle
*</p>
* <p>
* Description: 代理拦截处理类
* </p>
* <p>
* Author: mengfanyuan
* Email:kalvenmeng@163.com
* </p>
* <p>
* Date: 2014年8月27日
* </p>
*/
public class ProxyHandle implements InvocationHandler {
private Object target;

public ProxyHandle(Object target) {
this.target = target;
}

/* (non-Javadoc)
* <p>Title: invoke</p>
* <p>Description: 在该方法中对目标类方法调用的处理 </p>
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println(method.getName() + "方法执行前..");
Object result = method.invoke(target, args);
System.out.println(method.getName() + "方法执行后...");
return result;
}

}
5:,动态代理类生产器:ProxyFactory.java

/**
* ProxyFactory.java
* Created at 2014年8月27日
* Created by mengfanyuan
* Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
*/
package com.mfy.test.proxy.handle;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
* <p>
* ClassName: ProxyFactory
*</p>
* <p>
* Description: TODO
* </p>
* <p>
* Author: mengfanyuan
* Email:kalvenmeng@163.com
* </p>
* <p>
* Date: 2014年8月27日
* </p>
*/
public class ProxyFactory {

public static Object createProxyObj (Class targetInterface,InvocationHandler h) throws Exception {

return  Proxy.newProxyInstance(targetInterface.getClassLoader(),
new Class[]{targetInterface}, h);
}
}
6,测试类:TestMain.java

/**
* TestMain.java
* Created at 2014年8月27日
* Created by mengfanyuan
* Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
*/
package com.mfy.test.proxy.main;

import com.mfy.test.proxy.bean.User;
import com.mfy.test.proxy.handle.ProxyFactory;
import com.mfy.test.proxy.handle.ProxyHandle;
import com.mfy.test.proxy.service.IUserService;
import com.mfy.test.proxy.service.imp.UserServiceImp;

/**
* <p>
* ClassName: TestMain
*</p>
* <p>
* Description: TODO
* </p>
* <p>
* Author: mengfanyuan
* Email:kalvenmeng@163.com
* </p>
* <p>
* Date: 2014年8月27日
* </p>
*/
public class TestMain {

public static void main(String[] args) throws Exception {
User user = new User(1,"kalven","11111111");
IUserService serviceProxy = (IUserService)ProxyFactory.createProxyObj(IUserService.class, new ProxyHandle(new UserServiceImp()));
serviceProxy.save(user);
System.out.println();
serviceProxy.update(user);
System.out.println();
serviceProxy.delete(user.getId());
}

}
7,输出结果:

save方法执行前..

新增用户:kalven

save方法执行后...

update方法执行前..

更新用户:kalven

update方法执行后...

delete方法执行前..

删除用户Id:1

delete方法执行后...

8,结果分析总结:

从输出结果可以看到对目标类中的方法的调用都被拦截到ProxyHandle.java类中的方法invoke中去了;实现动态代理的关键类是Proxy和接口InvocationHandler;

9,对生成的动态代理类分析:

将第六步的测试类修改一下:
/**
* TestMain.java
* Created at 2014年8月27日
* Created by mengfanyuan
* Copyright (C) 2014 SHANGHAI KALVENMENG, All rights reserved.
*/
package com.mfy.test.proxy.main;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import sun.misc.ProxyGenerator;

import com.mfy.test.proxy.bean.User;
import com.mfy.test.proxy.handle.ProxyFactory;
import com.mfy.test.proxy.handle.ProxyHandle;
import com.mfy.test.proxy.service.IUserService;
import com.mfy.test.proxy.service.imp.UserServiceImp;

/**
* <p>
* ClassName: TestMain
*</p>
* <p>
* Description: TODO
* </p>
* <p>
* Author: mengfanyuan
* Email:kalvenmeng@163.com
* </p>
* <p>
* Date: 2014年8月27日
* </p>
*/
public class TestMain {

public static void main(String[] args) throws Exception {
User user = new User(1,"kalven","11111111");
IUserService serviceProxy = (IUserService)ProxyFactory.createProxyObj(IUserService.class, new ProxyHandle(new UserServiceImp()));
serviceProxy.save(user);
System.out.println();
serviceProxy.update(user);
System.out.println();
serviceProxy.delete(user.getId());

createProxyClassFile();
}

public static void createProxyClassFile() throws Exception{
String fileName = "UserServiceProxy";
byte[] date = ProxyGenerator.generateProxyClass(fileName, new Class[]{IUserService.class});
FileOutputStream out = new FileOutputStream(fileName + ".class");
out.write(date);
out.close();
}

}
执行完毕后可以在工程根路径下找到文件:UserServiceProxy.class

可以对该文件进行反编译查看生成的代理类的内容:

import com.mfy.test.proxy.bean.User;
import com.mfy.test.proxy.service.IUserService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class UserServiceProxy
extends Proxy
implements IUserService
{
private static Method m1;
private static Method m5;
private static Method m4;
private static Method m0;
private static Method m3;
private static Method m2;

public UserServiceProxy(InvocationHandler paramInvocationHandler)
throws
{
super(paramInvocationHandler);
}

public final boolean equals(Object paramObject)
throws
{
try
{
return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final void update(User paramUser)
throws
{
try
{
this.h.invoke(this, m5, new Object[] { paramUser });
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final void delete(Integer paramInteger)
throws
{
try
{
this.h.invoke(this, m4, new Object[] { paramInteger });
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final int hashCode()
throws
{
try
{
return ((Integer)this.h.invoke(this, m0, null)).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final void save(User paramUser)
throws
{
try
{
this.h.invoke(this, m3, new Object[] { paramUser });
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

public final String toString()
throws
{
try
{
return (String)this.h.invoke(this, m2, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}

static
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m5 = Class.forName("com.mfy.test.proxy.service.IUserService").getMethod("update", new Class[] { Class.forName("com.mfy.test.proxy.bean.User") });
m4 = Class.forName("com.mfy.test.proxy.service.IUserService").getMethod("delete", new Class[] { Class.forName("java.lang.Integer") });
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m3 = Class.forName("com.mfy.test.proxy.service.IUserService").getMethod("save", new Class[] { Class.forName("com.mfy.test.proxy.bean.User") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
return;
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
}


10,总结:

诚然,Proxy已经设计得非常优美,但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持interface代理的桎梏,因为它的设计注定了这个遗憾。回想一下那些动态生成的代理类的继承关系图,它们已经注定有一个共同的父类叫Proxy。Java的继承机制注定了这些动态代理类们无法实现对class的动态代理,原因是多继承在Java中本质上就行不通。有很多条理由,人们可以否定对
class代理的必要性,但是同样有一些理由,相信支持class动态代理会更美好。接口和类的划分,本就不是很明显,只是到了Java中才变得如此的细化。如果只从方法的声明及是否被定义来考量,有一种两者的混合体,它的名字叫抽象类。实现对抽象类的动态代理,相信也有其内在的价值。此外,还有一些历史遗留的类,它们将因为没有实现任何接口而从此与动态代理永世无缘。如此种种,不得不说是一个小小的遗憾。但是,不完美并不等于不伟大,伟大是一种本质,Java动态代理就是佐例。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: