java之动态代理

一、动态代理引入

package cn2;

public interface IUserDAO {
	/**
	 * 登录方法
	 */
	public void login();

	/**
	 * 注册方法
	 */
	public void register();

}
package cn2;

public class UserDAOImpl implements IUserDAO {

	@Override
	public void login() {
		System.out.println("用户登录");

	}

	@Override
	public void register() {
		System.out.println("用户注册");
	}

}
package cn2;

public class Test {
	public static void main(String[] args) {
		IUserDAO dao = new UserDAOImpl();
		dao.register();
		dao.login();

	}
}

用户注册

用户登录

如果我要给每个方法都增加权限校验和日志记录的话,那么代码实现如下:

package cn2;

public interface IUserDAO {
	/**
	 * 登录方法
	 */
	public void login();

	/**
	 * 注册方法
	 */
	public void register();

}
package cn2;

public class UserDAOImpl implements IUserDAO {

	@Override
	public void login() {
		System.out.println("用户登录");

	}

	@Override
	public void register() {
		System.out.println("用户注册");
	}

}
package cn2;

public class UserDAOImpl2 implements IUserDAO {
	private void actionCheck(){
		System.out.println("权限检查");
	}

	private void record(){
		System.out.println("日志记录");
	}

	@Override
	public void login() {
		this.actionCheck();
		System.out.println("登录");
		this.record();

	}

	@Override
	public void register() {
		this.actionCheck();
		System.out.println("注册");
		this.record();
	}

}
package cn2;

public class Test {
	public static void main(String[] args) {
		IUserDAO dao = new UserDAOImpl2();
		dao.register();
		dao.login();

	}
}

权限检查

注册

日志记录

权限检查

登录

日志记录

为什么要单独写一个类去实现接口,并增加权限校验和日志记录呢?因为我们在设计的时候,要保证对扩展功能开发,对修改代码关闭的原则。我定义了一个新的类去实现接口,就是想扩展原来接口的功能,而不是在原有的实现类上修改。

但是,如果都这样设计,是很可怕的事情,如果需求一旦变更,那我们需要定义好多好多的实现类,太复杂了。怎么办?

在生活中,我们会遇到很多问题,比如:我要租房子,但是我不认识房东,怎么办?找中介。同样的道理,我自己不想在修改代码去增加权限检查和日志记录的功能,那么我找一个代理对象去帮我实现不就可以了吗?

动态代理:就是在程序运行过程中产生的这个对象。

在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口接可以生成动态代理对象。JDK只针对接口做代理。

Proxy类中的方法创建动态代理对象

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

最终会调用InvocationHandler的方法

Object invoke(Object proxy,Method method,Object[] args)
package cn2;

public interface IUserDAO {
	/**
	 * 登录方法
	 */
	public void login();

	/**
	 * 注册方法
	 */
	public void register();

}
package cn2;

public class UserDAOImpl implements IUserDAO {

	@Override
	public void login() {
		System.out.println("用户登录");

	}

	@Override
	public void register() {
		System.out.println("用户注册");
	}

}
package cn2;

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

public class MyInvocationHandler implements InvocationHandler {

	private Object target;
	public MyInvocationHandler(Object target) {
		this.target = target;
	}

	/**
	 *返回动态代理对象
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {

		System.out.println("权限检查");

		Object invoke = method.invoke(target, args);

		System.out.println("日志记录");
		return invoke;
	}

}
package cn2;

import java.lang.reflect.Proxy;

public class Test {
	public static void main(String[] args) {
		//使用动态代理之前
		IUserDAO dao = new UserDAOImpl();
		dao.register();
		dao.login();

		System.out.println("-------------------");

		//使用动态代理之后

		IUserDAO proxy = (IUserDAO)Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), new MyInvocationHandler(dao));
		proxy.register();
		proxy.login();

	}
}

用户注册

用户登录

-------------------

权限检查

用户注册

日志记录

权限检查

用户登录

日志记录

时间: 2024-10-08 16:08:41

java之动态代理的相关文章

java的动态代理机制详解

在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于 Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是 java的动态代理机制,所以本篇随笔就是对java的动态机制进行一个回顾. 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Cla

Java JDK动态代理

通过JS操作DOM节点可能以节点为单位进行,比如添加节点,可以createElement,createTextNode,然后用appendChild把文本节点和容器节点绑定在一起,然后再用appendChild或insertBefor添加到DOM树中.但如果要往DOM树中动态添加大量的节点.就会很麻烦.而且每次都会刷新DOM,造成性能上的缺陷. 解决方法是使用文档碎片这个方法创建文档碎片. 我个人觉得应该把这个翻译成文档片段比较合适. 使用jQuery解决方案. <span style="

代理模式 &amp; Java原生动态代理技术 &amp; CGLib动态代理技术

第一部分.代理模式  代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务.(其实就是在代理类中关联一个委托类的实例,然后在代理类中进行包装). UML图如下: 第二部分.在Java中实现代理模式  按照代理的创建时期,代理类可以分

Java特性-动态代理

代理在开发中无处不在: 我们完成一个接口开发A,接口下有很多个实现类,这些类有些共同要处理的部分,比如每一个类都定义了接口A中的方法getXX(String name).我现在想把每次调用某个实现类的getXX方法时传的参数name记录在数据库某个表里,可问题是,,我们总不能在每个实现类里面去添加一个这样的处理模块吧?工作量太大了,把该处理逻辑写到一个static的工具类里面,然后每个实现类再去调用也挺麻烦.况且这个处理是给改接口专门使用的,放在工具类里也不合适啊.. 好办,我再写一个实现接口A

java的动态代理

最近在研究这个java的ssh三大框架,当看到这个spring的aop(aspect-orinted-programming)的时候,其中提到了这个java的动态代理机制,这个动态代理,我以前似乎看过,但是那是设计模式的事情.所以有一次搜索到这个动态代理,对这个动态代理进行一个研究,记录自己的进步. spring的aop编程是一个面向切面的编程思想,和这个面向对象的编程是一个补充的关系,不是一个对立的关系.面向对象强调和使用的从上到下的层次关系,但是aop编程使用的是从左到右的关系.一个是纵的关

java中动态代理实现机制

JAVA各种动态代理实现的比较 接口 interface AddInterface{ int add(int a, int b); } interface SubInterface{ int sub(int a, int b); } 实现类 class Arithmetic implements AddInterface, SubInterface{ @Override public int sub(int a, int b) { return a-b; } @Override public i

Java基础-动态代理

在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的. InvocationHandler 每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用

JAVA的动态代理机制

前文讲解了代理的基本概念和静态代理机制:       设计模式之代理模式 现在来谈谈JAVA的动态代理机制 在java的动态代理机制中有一个重要的接口invocationhandler和一个重要的类Proxy,让我们查看一下官方文档: InvocationHandler is the interface implemented by the invocation handler of a proxy instance. Each proxy instance has an associated 

(转)java的动态代理机制详解

原文出自:http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是java的动态代理机制,所以本篇随笔就是对java的动态机制进行一个回顾. 在java的动态代理机制中,有

[转载] java的动态代理机制详解

转载自http://www.cnblogs.com/xiaoluo501395377/p/3383130.html 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. 按照代理的创建时期,代理类可以分为两种. 静态代理