`
mamaoyuan625
  • 浏览: 173291 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

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()前后你可以嵌入一些安全 。日志的功能

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

 

 

  

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics