当前位置: 首页 > 编程笔记 >

Spring静态代理和动态代理代码详解

锺离德庸
2023-03-14
本文向大家介绍Spring静态代理和动态代理代码详解,包括了Spring静态代理和动态代理代码详解的使用技巧和注意事项,需要的朋友参考一下

本节要点:

Java静态代理
Jdk动态代理

1 面向对象设计思想遇到的问题

在传统OOP编程里以对象为核心,并通过对象之间的协作来形成一个完整的软件功能,由于对象可以继承,因此我们可以把具有相同功能或相同特征的属性抽象到一个层次分明的类结构体系中。随着软件规范的不断扩大,专业化分工越来越系列,以及OOP应用实践的不断增多,随之也暴露了一些OOP无法很好解决的问题。

现在假设系统中有三段完全相似的代码,这些代码通常会采用“复制”、“粘贴”方式来完成,通过这种方式开发出来的软件如图所示:

可能读者已经发现了这种做法的不足之处,如果有一天,蓝色背景的代码需要修改,那是不是要同时修改三个地方?如果不仅仅是这三个地方包含这段代码,而是100个,甚至是1000个地方,那会是什么后果?

记录日志在代码中无处不在---先来看一个例子:

为了跟踪应用程序的运行过程,很多方法都需要记录日志信息。我们一般这样写:

//log4j的使用见文章“log4j介绍”
import org.apache.log4j.Logger;
public class Person {
	private Logger logger = Logger.getLogger(Person.class);
	public void sleep(){
		logger.info(“开始执行时间:“ + new Date());
		System.out.println("睡觉中");
		logger.info(“执行结束时间:” + new Date());
	}
	public void eating(){
		logger.info("开始执行时间:“ + new Date()");
		System.out.println("正在吃饭中");
		logger.info("“执行结束时间:” + new Date()");
	}
}

提问:弊端在哪里?

l混淆了业务方法本身的职责

l维护工作量巨大

2解决方案1

静态代理:
   1、需要知道核心类(被代理类)是哪一个类,并且有什么方法。 
   2、非核心的代码需要重复写多次,显得代码的结构臃肿,形成代码冗余。
   3、非核心类(代理类)需要实现核心类(被代理类)实现的接口,也就是他们需要实现共同的接口,但是以核心类实现的接口(被代理类)为准。

l目地是将业务代码与日志代码完全分离,实现松散耦合.

l代理对象与被代理对象必须实现同一接口,在代理对象中实现与日志记录的相关服务,并在需要的时候呼叫被代理对象,而被代理对象只保留业务代码.

静态代理的实现

1)定义接口:

public interface IPerson {
	public abstract void sleep();
	public abstract void eating();
}

2) 被代理类

public class Person implements IPerson {
	public void sleep(){
		System.out.println("睡觉中");
	}
	public void eating(){
		System.out.println("正在吃饭中");
	}
}

3) 代理类

import org.apache.log4j.Logger;
public class PersonProxy implements IPerson {
	private IPerson person;
	private Logger logger = Logger.getLogger(PersonProxy.class);
	public PersonProxy(IPerson person) {
		this.person = person;
	}
	public void eating() {
		logger.info("开始执行时间:“ + new Date()");
		person.eating();
		logger.info("“执行结束时间:” + new Date()");
	}
	public void sleep() {
		logger.info("开始执行时间:“ + new Date()");
		person.sleep();
		logger.info("“执行结束时间:” + new Date()");
	}
}

4) 测试类

package com.aptech.aop2;
public class PersonTest {
	public static void main(String[] args) {
		IPerson proxy = new PersonProxy(new Person());
		proxy.eating();
		proxy.sleep();
	}
}

静态代理的弊端:

一个代理接口只能服务于一种类型的对象.对于稍大点的项目根本无法胜任.

3 解决方案2-动态代理

InvocationHandler:每一个动态代理类都必须实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的invoke方法来进行调用。

在JDK1.3之后加入了可协助开发的动态代理功能.不必为特定对象与方法编写特定的代理对象,使用动态代理,可以使得一个处理者(Handler)服务于各个对象.
一个处理者的类设计必须实现java.lang.reflect.InvocationHandler接口.
通过InvocationHandler接口实现的动态代理只能代理接口的实现类.

动态代理实现

1) 处理者(Handler)

public class DynaProxyHandler implements InvocationHandler {
	private Logger logger = Logger.getLogger(DynaProxyHandler.class);
	private Object target;
	//被代理对象
	public void setTarget(Object target) {
		this.target = target;
	}
	public Object invoke(Object proxy, Method method, Object[] args)
	              throws Throwable {
		logger.info("执行开始时间:" + new Date());
		Object result = method.invoke(target, args);
		logger.info("执行结束时间:" + new Date());
		return result;
		//返回method执行结果
	}
}

2) 生产代理对象的工厂

import java.lang.reflect.Proxy;
public class DynaProxyFactory {
	//obj为被代理对象
	public static Object getProxy(Object obj){
		DynaProxyHandler handler = new DynaProxyHandler();
		handler.setTarget(obj);
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);
	}
}

3) 测试类

public class PersonTest {
	public static void main(String[] args) {
		IPerson person = (IPerson) DynaProxyFactory.getProxy(new Person());
		//返回代理类,代理类是JVM在内存中动态创建的,该类实现传入的接口数组的全部接口(的全部方法).
		person.eating();
		person.sleep();
	}
}

总结

以上就是本文关于Spring静态代理和动态代理代码详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:

Spring常用配置及解析类说明

SpringMVC拦截器实现单点登录

Java编程实现springMVC简单登录实例

如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

 类似资料:
  • 本文向大家介绍浅谈Java代理(jdk静态代理、动态代理和cglib动态代理),包括了浅谈Java代理(jdk静态代理、动态代理和cglib动态代理)的使用技巧和注意事项,需要的朋友参考一下 一、代理是Java常用的设计模式,代理类通过调用被代理类的相关方法,并对相关方法进行增强。加入一些非业务性代码,比如事务、日志、报警发邮件等操作。 二、jdk静态代理 1、业务接口 2、业务实现类 3、代理类

  • 本文向大家介绍Java静态代理和动态代理总结,包括了Java静态代理和动态代理总结的使用技巧和注意事项,需要的朋友参考一下 静态代理 第一种实现(基于接口): 1》接口 2》目标类,至少实现一个接口 3》代理类(与目标类实现相同接口,从而保证功能一致) 3》测试 第二种实现(基于目标类): 1>目标类 2>代理类(通过继承目标类,保证功能一致) 3>测试 动态代理 动态代理的代理类是在程序运行期间

  • 本文向大家介绍详解 Java静态代理,包括了详解 Java静态代理的使用技巧和注意事项,需要的朋友参考一下   今天要介绍的是一个Java中一个很重要的概念——代理。   什么是代理?联系生活想想看,代理似乎并不陌生,最形象的代表便是经纪人,明星一般都有经纪人,经纪人作为中间人,负责代理明星的相关事宜,比如说,有人要请明星去唱歌表演,一般不会直接跟明星联系,而是联系他的经纪人,他的经纪人来负责安排

  • 本文向大家介绍Java动态代理静态代理实例分析,包括了Java动态代理静态代理实例分析的使用技巧和注意事项,需要的朋友参考一下 代理模式:为其他对象提供一种代理以控制某个对象的访问。用在:在某些情况下,一个客户不想或者不能直接访问另一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用,代理对象还可以完成它附加的操作。 例子:就像房东、租客、中介的关系。中介(代理对象)为房东(真实对象)出租

  • 本文向大家介绍java 反射和动态代理详解及实例代码,包括了java 反射和动态代理详解及实例代码的使用技巧和注意事项,需要的朋友参考一下 一、java中的反射 1.通过反射加载类的属性和方法实例代码: 2.类加载器ClassLoader 3.动态代理 静态代理:代理类和目标对象的类型都是在编译期间确定下来,不利于程序的扩展。同时每个代理类只能为一个接口服务,这样一来程序开发中必然产生过多的代理。

  • 本文向大家介绍详解Java JDK动态代理,包括了详解Java JDK动态代理的使用技巧和注意事项,需要的朋友参考一下   今天来看看Java的另一种代理方式——JDK动态代理   我们之前所介绍的代理方式叫静态代理,也就是静态的生成代理对象,而动态代理则是在运行时创建代理对象。动态代理有更强大的拦截请求功能,因为可以获得类的运行时信息,可以根据运行时信息来获得更为强大的执(骚)行(操)力(作)。

  • 我在数字海洋上有一个水滴,我正在使用它来主持一个网站和该网站的API。 null

  • 本文向大家介绍Spring AOP手动实现简单动态代理的代码,包括了Spring AOP手动实现简单动态代理的代码的使用技巧和注意事项,需要的朋友参考一下 什么是AOP我们先来看一张图 图中A就是通知,比如你要给每个方法前都加一个before()方法,目标类的每一个方法叫joinpoint(切入点),每个切入点都会用到通知,把通知和切入点连起来,点成线,线成面,这就是切面,也就是AOP,下面我们来