Java代理总结

Java代理机制 分类:

 

静态代理:继承代理【基于抽象类的代理】

               聚合代理【基于接口的代理】

 

动态代理:jdk代理【只针对接口,不能针对类】

               cglib代理【针对类实现代理,主要对指定的类产生一个子类,并且覆盖其中的方法实现类增强,因为采取的是继承的方式,无法对final类进行代理,hibernate使用的是cglib代理】

 

 

1.  聚合代理

 

package proxy2;
/**
 *************************************
  * @Title   Movable.java
  * @Author  张作强
  * @Date    2010-8-22
  * @Comment 聚合代理是基于接口的代理,先声明接口
 *************************************
 */
public interface Movable {
	void move();
}

 

package proxy2;

import java.util.Random;
/**
 *************************************
  * @Title   Tank.java
  * @Author  张作强
  * @Date    2010-8-22
  * @Comment 被代理的实体类,实现接口
 *************************************
 */
public class Tank implements Movable {
	
	public void move() {
		long begin=System.currentTimeMillis();
		System.out.println("Tank Moving");
		try {
			Thread.sleep(new Random().nextInt(10000));
		} catch (InterruptedException e) {
				e.printStackTrace();
			}
			long end=System.currentTimeMillis();
			System.out.println("Tank Move :"+(end-begin));
		}
}

 

package proxy2;
/**
 *************************************
  * @Title   TankTranProxy.java
  * @Author  张作强
  * @Date    2010-8-22
  * @Comment 代理的实现1,在调用被代理类的方法前后实现事物操作
 *************************************
 */
public class TankTranProxy implements Movable {
	
	Movable tank;
	
	//实现接口
	public void move() {
		System.out.println("Begin Transaction....");
		//这里调用的是构造函数传递过来的实现了接口的类
		tank.move();
		System.out.println("End Transaction....");
	}
	
	//构造函数,将实现接口的对象作为参数传递给构造函数
	public TankTranProxy(Movable tank) {
		super();
		this.tank = tank;
	}
}

 

package proxy2;
/**
 *************************************
  * @Title   TankLogProxy.java
  * @Author  张作强
  * @Date    2010-8-22
  * @Comment 代理的实现2,在调用被代理类的方法前后实现日志操作
 *************************************
 */
public class TankLogProxy implements Movable {
	
	Movable t;
	
	public TankLogProxy(Movable m) {
		super();
		this.t = m;
	}
	
	public void move() {
		System.out.println("Loging....");
		t.move();
		System.out.println("End Loging.....");
	}
}

 

package proxy2;

public class TestMain {
	public static void main(String[] args) {
		
		Tank tank=new Tank();
		
		//在执行被代理类之前先进行事务操作
		Movable tankTran=new TankTranProxy(tank);
		
		//在执行被代理类之前先进行日志操作
		Movable tankLog=new TankLogProxy(tankTran);
		
		//注:也可以把以上两行代码反过来些,就在执行被代理类之前先执行日志操作,然后进行事务操作
		//然后再执行被代理类的方法
		tankLog.move();
	}
}

 

结果:

Loging....

Begin Transaction....

Tank Moving

Tank Move :8375

End Transaction....

End Loging.....

 

2.  继承代理

 

package proxy3;

//被代理的类
public abstract class Tank {
	
	public void move(){
		System.out.println("Tank Moving... ");
	}
}

 

package proxy3;

public class TankProxy extends Tank {
	
	//以继承的方式实现代理
	
	//重写父类的方法
	public void move(){
		
		long start = System.currentTimeMillis();
		System.out.println("Before Moving:" + start);
		
		//注:该处调用的是Tank类的move,所以是代理Tank类的方法
		super.move();
		long end = System.currentTimeMillis();
		System.out.println("After Moving:" + end);
		System.out.println("您共运行了:" + (start - end) + "毫秒");
	}
}

 

package proxy3;

public class Test {
	public static void main(String[] args) {
		TankProxy tankProxy = new TankProxy();
		tankProxy.move();
	}
}

 

结果:

Before Moving:1282459642796

Tank Moving... 

After Moving:1282459642796

您共运行了:0毫秒

 

3.  jdk动态代理

 

package proxy4;

// jdk动态代理是基于接口实现的,第一步,先定义接口
public interface UserManager {
	void save(String name,String password);
	void delUser(int id);
}

 

package proxy4;

//被代理的类实现接口
public class UserManagerImpl implements UserManager {

	public void save(String name, String password) {
		System.out.println("UserManagerImpl.save..用户名:" + name
							+ "用户密码:" + password);
	}

	public void delUser(int id) {
		System.out.println("UserManagerImpl.delUser..用户ID:"+id );
	}
}

 

package proxy4;

//在执行被代理类的方法时,插入安全检查的类
public class Security {
	
	public void securityCheck(){
		System.out.println("security Checking...");
	}
}

 

package proxy4;

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

public class UserManagerProxy implements InvocationHandler {
	
	UserManager userManager;
	
	//生成代理类
	public Object getUserManagerProxy(UserManager userManager){
		this.userManager = userManager;
		return Proxy.newProxyInstance(userManager.getClass().getClassLoader(),
									  userManager.getClass().getInterfaces(), this);
	}
	
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
		System.out.println("----------------- 参数列表  -----------------");
		for (int i = 0; i < args.length; i++) {
			System.out.println(args[i]);
		}


		System.out.println("----------------- 调用的方法  -----------------");
		System.out.println(method.getName());

		System.out.println("----------------- 安全检查  -----------------");
		Security security = new Security();
		security.securityCheck();

		System.out.println("----------------- 执行方法  -----------------");
		Object object=method.invoke(userManager, args);
		System.out.println("\n--------------------------------—-------\n");
		return object;
	}
}

 

package proxy4;

public class Test {
	public static void main(String[] args) {
		
		//这里必须使用接口进行类型转换
		UserManager userManager=(UserManager)new UserManagerProxy().
								getUserManagerProxy(new UserManagerImpl());
		userManager.save("张三","123456");
		userManager.delUser(3);
	}
}

 

结果:

----------------- 参数列表  -----------------

张三

123456

----------------- 调用的方法  -----------------

save

----------------- 安全检查  -----------------

security Checking...

----------------- 执行方法  -----------------

UserManagerImpl.save..用户名:张三用户密码:123456

 

--------------------------------—-------

 

----------------- 参数列表  -----------------

3

----------------- 调用的方法  -----------------

delUser

----------------- 安全检查  -----------------

security Checking...

----------------- 执行方法  -----------------

UserManagerImpl.delUser..用户ID:3

 

--------------------------------—-------

 

4.  cglib动态代理

 

cglib代理必须先引入包:cglib.jar或者别的版本

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值