博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring——AOP学习(静态代理和动态代理模式)
阅读量:3940 次
发布时间:2019-05-24

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

Spring——AOP学习(静态代理和动态代理模式)

一、代理模式

我们知道学习Spring最重要的两个知识点就是IOC和AOP,AOP的主要思想就是动态代理模式。在了解AOP之前我们必须学习动态代理模式。

代理模式又分为静态代理和动态代理。

二、静态代理

在学习多线程的时候我们已经学了了静态代理,我们这里回顾一下。什么是静态代理?

拿出之前学习静态代理的例子:
加入你要结婚,是不是需要找个婚庆公司来帮你结婚,但是实际上结婚的还是你自己,婚庆公司也就是哪个代理对象,它可以帮你做婚前的准备等等工作,你只需要专注于结婚这件事就行了。这就是静态代理模式。代理角色需要和真实的角色实现一个共同的结婚接口。我们来回忆一下代码是怎么简单实现静态代理的:

/** * 静态代理模式: *              1.真实角色 *              2.代理角色 *              3.共同要实现的接口 *     注意: *          代理对象代理真实角色去结婚,真实结婚的还是真实对象。 *     优点: *          代理对象可以做很多真实对象做不了的事情,真实对象专心的去做自己的事情 */public class StaticProxy {
public static void main(String[] args) {
//结婚,让代理帮你,至于要将你作为对象交给代理对象,它就可以帮你完成结婚 //获取真实角色 You you = new You(); //获取代理角色,并将真实角色传给代理角色 WeddingCompany weddingCompany = new WeddingCompany(you); //代理觉得帮你去结婚,实际上还是你自己去结婚的,不过结婚所附带的是就不用你去做了,你只需要专注结婚,其他的事情代理帮你做好 weddingCompany.happyMarry(); }}//你class You implements Marry{
@Override public void happyMarry() {
System.out.println("你要结婚了"); }}//你的代理对象:婚庆公司class WeddingCompany implements Marry{
//婚庆公司需要你这个人,所以将you对象组合进来 private You you; public WeddingCompany(You you) {
this.you = you; } @Override public void happyMarry() {
//结婚之前代理帮真实角色做的事 System.out.println("结婚之前,布置现场"); //真实角色只用专注于结婚就行了 you.happyMarry(); //结婚之后代理帮真实角色做的事 System.out.println("结婚之后,惨不忍睹"); }}//你们都要做的事(接口):结婚interface Marry{
void happyMarry();}

这就是简单的实现了静态代理模式,在我们多线程的第二种创建方式(实现Runnable接口)中就体现了静态代理模式的思想。

那么静态代理有什么好处呢?

  • 使用静态代理模式可以让真实角色认认真真的完成自己的工作,更加纯粹,不去关注一些公共的事情
  • 公共业务需要由代理对象来实现,实现了业务的分工,体现了解耦的思想
  • 公共业务需要扩展的话非常的方便

那么静态代理又有哪些缺点?

  • 如果真实角色有很多,那么代理角色的工作量就相当的大了,开发效率就会变得很低

那么动态代理就来了…

三、动态代理

动态代理和静态代理的角色都是一样的,唯一的区别就是静态代理模式的代理类(婚庆公司)是我们提前写好的,但是动态代理的代理类是动态生成的。

动态代理分为两大类:

  • 基于JDK原生态的接口实现
  • 基于类实现
    如:CGLIB、Javassist、ASM等

其中用的比较多的是Javassist来生成动态代理。

那么我们了解动态代理之前需要掌握两个类:

  • InvocationHandler:
    InbocationHandler类是由代理实例调用处理程序实现的接口。
    invoke(Object proxy,方法 method,Object[] args)方法处理代理实例上的方法调用并返回结果。
  • Proxy:
    Proxy提供了创建动态代理类和实力的静态发方法,他也是由这些方法创建的所有动态代理类的超类。
    newProxyInstance(ClassLoader loader, 类<?>[] interfaces, InvocationHandler h)方法返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。

代码实现动态代理:

一个共同的接口:结婚

package com.muhan.proxy;//共同的接口:结婚public interface Marry {
//结婚 void happyMarry();}

真实角色:you

package com.muhan.proxy;//真实角色:你,实现共同结婚接口public class You implements Marry{
//结婚 public void happyMarry() {
System.out.println("你结婚了"); }}

代理角色(动态生成)

package com.muhan.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;//动态代理类生成的接口对象public class WeddingCompany implements InvocationHandler {
//维护一个真实角色的引用 private Object realObject; public void setYou(Object realObject) {
this.realObject = realObject; } //动态生成代理类 public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), realObject.getClass().getInterfaces(),this); } //proxy:代理类;method:代理类的调用处理程序方法的对象 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
beforeOfMarry(); Object result = method.invoke(realObject, args); afterOfMarry(); return result; } //结婚前婚庆公司帮你做的事 private void beforeOfMarry() {
System.out.println("布置婚礼现场"); } //结婚后婚庆公司帮你做的事 private void afterOfMarry() {
System.out.println("制作录像剪辑视频"); }}

测试类:

package com.muhan.proxy;public class ProxyTest {
public static void main(String[] args) {
//创建一个真实角色 You you = new You(); //创建一个动态代理角色 WeddingCompany weddingCompany = new WeddingCompany(); //将真实角色交给代理角色 weddingCompany.setYou(you); //代理角色代理真实角色结婚 Marry proxy = (Marry) weddingCompany.getProxy(); proxy.happyMarry(); }}

结果:

在这里插入图片描述

动态代理的好处:

  • 可以使真实角色专注于做自己的事情,不用去关注一些公共的事情
  • 公共的业务由代理来完成,实现业务的分工
  • 公共业务需要扩展的话,可以更加集中和方便
  • 一个动态代理一般代理一类业务,一个动态理;也可以代理多个类、接口

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

你可能感兴趣的文章
报名启动!巨杉数据库 2021 湖仓一体技术大赛带你进入分布式技术的星辰大海
查看>>
H2数据库用户自定义函数方法及范例
查看>>
关于系统中使用多个PropertyPlaceholderConfigurer的配置
查看>>
厦大06应用金融硕士研究生推荐精读书目
查看>>
《越人歌》-诗经
查看>>
Jetty嵌入式服务器的JNDI快速配置指南
查看>>
夜, 北京
查看>>
图示ExtJS商业智能的仪表盘配置系统 - (Season 1)
查看>>
MAC 显示隐藏文件的方法
查看>>
Ext.Ajax教程,及Get和Post请求的使用拾遗
查看>>
Mac下配制Maven过程
查看>>
Mac下的Eclipse3.4反编译插件
查看>>
Mac截图快捷键大全
查看>>
扩展Spring Security-用户密码自定义加密的快速实现
查看>>
Log4j异步日志简明配制
查看>>
扩展Spring Security-国际化终极配制
查看>>
在Mac OS系统下得Linux虚拟机中安装Confluence3
查看>>
在Eclipse中调试Jetty应用的配置(XML配置文件方式)
查看>>
Ext-3.1.0下组件中按钮居中问题的记要
查看>>
MacOS下使用screen命令运行后台程序
查看>>