博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
代理模式、静态代理、动态代理、aop
阅读量:4047 次
发布时间:2019-05-25

本文共 3535 字,大约阅读时间需要 11 分钟。

关键字: 模式

    首先要解释一下什么是代理模式:网上看了好多关于代理的解释我感觉都不是太令人满意,按照我个人的理解,代理模式的作用其实就是为一个对象提供一种代理以控制这个对象,然后把这个代理提供给别人来使用。代理模式会在那些情况下使用呢?在某些情况下,一个客户不想或者不能直接引用或者说在引用目标对象前后要进行一些额外的工作时候,代理对象可以在客户端和目标对象之间起到中介的作用。

代理模式的角色有3种:

抽象角色:声明真实对象和代理对象的共同接口;

代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作前后,附加其他的操作,相当于对真实对象进行封装一些额外的服务。
真实角色:代理角色所代表的真实对象,是代理最终要引用的对象。

静态代理:代理类中引用实在的被代理类;动态代理:代理类中不引用实在的被代理类,动态注入。

静态代理的实例:

抽象角色:UserDAO

publicinterface UserDAO {

    publicvoid saveUser(User user);

}

真实角色:UserDAOImp

publicclass UserDAOImp implements UserDAO {

    publicvoid saveUser(User user) {

       }

}

代理角色:UserDAOProxy

publicclass UserDAOProxy implements UserDAO {

    private UserDAO userDao;

    UserDAOProxy(UserDAO userDao){

       this.userDao = userDao;

    }

    publicvoid saveUser(User user) {

       beforeSaveUser();

       userDao.saveUser(user);

       afterSaveUser();

    }

    privatevoid afterSaveUser() {

    }

    privatevoid beforeSaveUser() {

    }

}

运行:

 publicclass TestUserDAOProxy {

    publicstaticvoid main(String[] args) {

       UserDAO userDAO = new UserDAOImp();

       UserDAO proxy = new UserDAOProxy(userDAO);

       User user = new User();

       proxy.saveUser(user);

    }

}

 动态代理的实例:

抽象角色:

publicinterface HelloWorld {

    publicvoid sayHello();

}

真实角色:

publicclass HelloWorldImpl implements HelloWorld {

    publicvoid sayHello() {

       System.out.println("hello world");

    }

}

Handler

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

public class HelloWorldHandler implements InvocationHandler {

       Object obj;

       HelloWorldHandler(Object obj) {

              this.obj = obj;

       }

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

                     throws Throwable {

              this.doBefore();

              Object o = method.invoke(obj, args);

              this.doAfter();

              return null;

       }

       public void doBefore() {

              System.out.println("do this before");

       }

       public void doAfter() {

              System.out.println("do this after");

       }

}

具体调用:

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Proxy;

publicclass TestProxy {

    publicstaticvoid main(String[] args) throws IllegalArgumentException,

           InstantiationException, IllegalAccessException,

           InvocationTargetException {

       HelloWorld hw1 = new HelloWorldImpl();

       HelloWorldHandler hh = new HelloWorldHandler(hw1);

       HelloWorld proxy1 = (HelloWorld) Proxy.newProxyInstance(hw1.getClass()

              .getClassLoader(), hw1.getClass().getInterfaces(), hh);

//proxy1就是动态代理,这样就减少了代理和添加业务方法的耦合,具体业务以及添加的业务在handler里面已经实现

       proxy1.sayHello();

       hw1.sayHello();

    }

}

从此可以看出动态代理是基于interface classloader动态创建一个代理对象,如果你能理解这点就很容易理解spring aop

看下面一段代码,来源于spring in action

<beans>

    <bean id="quest"

       class="com.springinaction.chapter01.knight.HolyGrailQuest" />

    <bean id="knightTarget"

       class="com.springinaction.chapter01.knight.KnightOfTheRoundTable">

       <constructor-arg>

           <value>Bedivere</value>

       </constructor-arg>

       <property name="quest">

           <ref bean="quest" />

       </property>

    </bean>

    <bean id="minstrel"

       class="com.springinaction.chapter01.knight.MinstrelAdvice" />

    <bean id="knight"

       class="org.springframework.aop.framework.ProxyFactoryBean">

       <property name="proxyInterfaces">

           <list>

              <value>

                  com.springinaction.chapter01.knight.Knight

              </value>

              <value>

                  com.springinaction.chapter01.knight.Knight2

              </value>  

           </list>

       </property>

       <property name="interceptorNames">

           <list>

              <value>minstrel</value>

           </list>

       </property>

       <property name="target">

           <ref bean="knightTarget" />

       </property>

    </bean>

</beans>

       BeanFactory factory = new XmlBeanFactory(new ClassPathResource(

              "applicationContext.xml"));

       Knight knight = (Knight) factory.getBean("knight");

//knight就是一个动态代理对象!

knight.embarkOnQuest();

看到上面的配置文件,然后再看一下动态代理,你会发现spring aop就是基于动态代理模式来实现的

转载地址:http://yefci.baihongyu.com/

你可能感兴趣的文章
S3C2440中对LED驱动电路的理解
查看>>
《天亮了》韩红
查看>>
Windows CE下USB摄像头驱动开发(以OV511为例,附带全部源代码以及讲解) [转]
查看>>
关于货币符号以及发音、币别码
查看>>
关于预处理器的学习
查看>>
ARM,S3C2410中脉宽调制定时器
查看>>
Zebra Bar-One 不能批量打印离散号码
查看>>
Platform创建WinCE内核时的编译错误
查看>>
玻璃杯
查看>>
柳永 《雨霖铃》
查看>>
MD2410开发板通过仿真器烧Bootloader简单流程
查看>>
MD2410仿真器烧Bootloader补充[1]:JTAG
查看>>
Meav《One I Love》
查看>>
林锐《高质量C++/C 编程指南》附录之《C++/C 代码审查表》
查看>>
林锐《高质量C++/C 编程指南》附录之《C++/C 编程质量试题》
查看>>
SC6600D_init.s
查看>>
最近比较烦
查看>>
祝福君君
查看>>
南澳西冲东冲穿越2日游
查看>>
又是一年毕业时
查看>>