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-静态代理

  • 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();

         }

}

静态代理的弊端:

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

解决方案2-动态代理

  • 在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();

         }

}
时间: 2024-11-03 21:55:56

spring静态代理和动态代理的相关文章

Spring静态代理与动态代理

代理模式 1.什么是代理模式? 真实生活中有一种房屋中介是这样的,租客根本就不知道房东是谁,一切签合同.交租金.交钥匙等操作都直接和中介公司发生.我们把这种模式称之为代理模式. 代理模式:客户端直接使用的都是代理对象,不知道目标对象是谁,此时代理对象可以在客户端和目标对象之间起到中介的作用. 2.特点 代理对象完全包含目标对象,客户端使用的都是代理对象的方法,和目标对象没有直接关系 3.职责 把不是目标对象该做的事情从目标对象上撇开——职责清晰. 4.分类 静态代理:在程序运行前就已经存在代理类

【设计模式】代理模式:静态代理,动态代理,spring aop

代理模式分为静态代理和动态代理.我们拿链家来举例子,我们本人是真实的对象,有真实的业务需求:需要去找房子:链家是中介,是代理类,他来帮我执行找房子的这个操作. 静态代理: 1.实现一个接口 public interface SearchHome { public void search(); } 2.构建实现接口的委托类 public class Master implements SearchHome { @Override public void search() { System.out.

Atitit 代理CGLIB 动态代理 AspectJ静态代理区别

Atitit 代理CGLIB 动态代理 AspectJ静态代理区别 1.1. AOP 代理主要分为静态代理和动态代理两大类,静态代理以 AspectJ 为代表:而动态代理则以 spring AOP 为代表 1 1.2. JDK动态代理是模拟接口实现的方式,cglib是模拟子类继承的方式1 1.3. CGLIB代理模式的缺点 在static和final方法上应用横切关注点也是无法做到的.2 1.1. AOP 代理主要分为静态代理和动态代理两大类,静态代理以 AspectJ 为代表:而动态代理则以 

Java:静态代理and动态代理

代理模式是常用的设计模式,其特征是代理类与委托类具有相同的接口,在具体实现上,有静态代理和动态代理之分.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务,也就是说代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 静态代理和动态代理的一个显著区别: 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就

java 代理模式(静态代理、动态代理、Cglib代理) 转载

Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法 代理模式最大的特点就是代理类和实际业务类实现同一个接口(或继承同一父类),代理对象持有一个实际对象的引用,外部调用时操作的是代理对象,而在代理对象的内部实现中又会去调

静态代理、动态代理

代理模式最大的优势就是能够解耦,在spring中也是广泛使用.spring中一个重要的特性就是aop,aop是个啥东西呢?其实很简单,比如现在有个业务方法,那这个业务方法很重要,涉及到非常重要的业务数据,那对于广大企业应用来说,为了以后能够及时的定位问题,需要记录相关入参以及出参到日志表. 但是对于企业应用来说,需要记录日志的地方应该是蛮多的,如果每个方法中都手动的去写这些记录日志的东西,就会特别的冗余,那使用代理模式就可以解决. 一.静态代理 1.User接口 package com.ty.s

zbb20180930 代理模式 -静态代理-jdk动态代理-cglib动态代理

CGLIB与JDK动态代理区别 区别: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理.而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理. 1.如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2.如果目标对象实现了接口,可以强制使用CGLIB实现AOP 3.如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB

java中静态代理和动态代理

一.概述 代理是一种模式,提供了对目标对象的间接访问方式,即通过代理访问目标对象.如此便于在目标实现的基础上增加额外的功能操作,前拦截,后拦截等,以满足自身的业务需求,同时代理模式便于扩展目标对象功能的特点也为多人所用. 按照代理的创建时期,代理类可以分为两种: 静态:由程序员创建代理类或特定工具自动生成源代码再对其编译.在程序运行前代理类的.class文件就已经存在了. 动态:在程序运行时运用反射机制动态创建而成. 我们根据加载被代理类的时机不同,将代理分为静态代理和动态代理.如果我们在代码编

静态代理与动态代理

记得刚接触代理,是在大话设计模式,最近在技术总结和学些java的过程又接触到静态代理和动态代理,尤其是动态代理,在学习AOP时,用到了动态代理,下面我用一些例子来对静态代理和动态代理做个总结. 其实用了代理之后最大的好处就是隐藏了真实类(委托类),这样更加安全,而静态代理和动态代理最大的区别就是,静态代理的代理类是程序员自己写的,在程序运行之前就已经存在的,而动态代理则是在程序运行时动态生成的,而且因为动态代理更加灵活,也常被应用. 首先先用一张UML图来理解一下代理是怎么回事? 其实静态代理就