JDK的动态代理

1:目标对象实现的接口
package com.lovo.spring;

public interface UserManager {
	public void addUser(String username,String password);
	public void deleteUser(int id);


}

 

2:目标对象

public class UserManagerImpl implements UserManager {

	public void addUser(String username, String password) {
			System.out.println("---------userManagerImpl.addUser()--------");
	}

	public void deleteUser(int id) {
		System.out.println("---------userManagerImpl.deleteUser()--------");

	}


}

 3:创建代理对象

package com.lovo.spring;

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

public class SecurityHandler1 implements InvocationHandler {
	private Object targetObject;
	public Object newProxy(Object targetObject) {

		this.targetObject = targetObject;
		return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
																  targetObject.getClass().getInterfaces(),
																  this);
	}
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
//安全性检查
		checkSecurity();
		
		Object ret = null;
		
		try {

			ret = method.invoke(this.targetObject, args);

		} catch (Exception e) {
			e.printStackTrace();
		}
		return ret;
	}

	private void checkSecurity() {
		System.out.println("---------安全性检查-------");
	}

}

 

 4:测试类

package com.lovo.spring;

public class ClientTest {

	public static void main(String[] args) {
		SecurityHandler hander = new SecurityHandler();
		UserManager userManager =
									(UserManager) hander.newProxy(new UserManagerImpl());
		// userManager.addUser("xiao", "aa");
		userManager.deleteUser(2);
	}

}

 

分析原理:

1:现在是动态代理所以创建的代理对象必须实现  java.lang.reflect.InvocationHandler;

2: private Object targetObject;

  把目标对象组合进来

 代理模式:定义一个接口  目标对象实现这个接口,而且代理对象一定要把目标对象组合进来。

3: 这个方法的目的是传入目标对象返回代理对象

public Object newProxy(Object targetObject) { 	
	this.targetObject = targetObject;
	return Proxy.newProxyInstance(
targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
 this);
	}
  • newProxy(Object targetObject) 传入目标对象返回代理对象
  • return  Proxy.newProxyIntance(参数1,参数2,参数3);
  • 参数1:目标对象的类加载器
  • 参数2:目标对象实现的所有接口(数组)
  • 参数3:实现了InvocationHandler 这个接口的类

4:

public Object invoke(Object proxy, Method method, Object[] args)	
  •  这是一个拦截器,也就说当你在测试类中
	UserManager userManager =
	(UserManager) hander.newProxy(new UserManagerImpl());

 

然后调用这些接口中的方法(其实调用的是接口的实现类的具体方法)

	 userManager.addUser("xiao", "aa");
	 userManager.deleteUser(2);

 

的时候,就会先调用invoke这个拦截方法

    重要说明:(自己的理解)

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

    参数1:proxy:就是利用目标对象创建出来的代理对象

   参数2:method:jdk帮助文档中的描述:

 

 (对应于在代理实例上调用的接口方法的 Method 实例。

Method 对象的声明类将是在其中声明方法的接口,

该接口可以是代理类赖以继承方法的代理接口的超接口。)

 如果要把这个method实例在控制台打印出来可以看到:

public abstract void com.lovo.spring.UserManager.deleteUser(int)

 说明:这个deleteUser(int) 就是我们在接口中定义的方法,目标对象实现的方法,也就是我们想要调用的方法,只不过在这里是一个Method实例而已。

  参数3:Object[] args

	for (int i = 0; i < args.length; i++) {

				System.out.println(args[i]);
			}

 结果:

 

                 xiao aa

                   2

说明:这就是我们 在测试类中调用方法时,传入的参数,在这里被拦截了

 

5:method.invoke(this.targetObject, args);

  利用method这个实例,传入目标对象,就可以执行你要调用的方法

  其实这里才是真正的调用你想调用的方法

当然在method.invoke()前后你可以嵌入一些安全 。日志的功能

如上:嵌入的安全检查方法

 

 

  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值