我们来定义一下  AOP(面向切面编程)

  它是面向对象的一种补充或者是一种增强,它在这基础上增加了一些

而外的功能增强。

  它可以在原有的行为不改变的前提,在这之前或者之后完成一些而外

的事情。

而AOP用的思想和模式就是代理模式。

代理模式分为两种:

1.静态代理。

  静态代理的代理类是开发人员自行编写的,并且在编译期就已经

确定。编写相应的接口和实现类,同时编写一个代理类实现这个接口。

  缺点:

  1.需要为每一个目标对象编写相应得代理实例,从而代理不同的业

务逻辑。

  2.当接口发生变动时,所有的代理类和实现了都必须修改。

举个小例子:

Interface:Computer

package org.proxy;

/**
* Created by Administrator on 2016/11/25.
*/
//编写一个接口
public interface Computer {
public void sell( int money );
}

Class:LenovoComputer

package org.proxy;

/**
* Created by Administrator on 2016/11/25.
*/
//编写一个类,继承Computer接口
public class LenovoComputer implements Computer { //重写其方法
@Override
public void sell( int money ) {
System.out.println( "实收金额" + money );
}
}

Proxy:LenovoProxy

package org.proxy;

/**
* Created by Administrator on 2016/11/25.
* 编写一个代理对象
*/
public class LenovoProxy implements Computer { //定义要代理的对象
private LenovoComputer lenovo; //在构造方法中传入LenovoComputer参数
public LenovoProxy( LenovoComputer lenovo ) {
this.lenovo = lenovo;
} @Override
public void sell(int money) {
//在将成本交给厂家之前,先扣去利润
money = money - 500;
System.out.println( "代理商赚取了500" );
//调用方法
lenovo.sell( money );
}
}

Main方法:

package org.proxy;

/**
* Created by Administrator on 2016/11/25.
*/
public class User {
//main方法
public static void main(String[] args) {
//实例化代理对象,代理LenovoComputer,调用其方法
Computer c = new LenovoProxy( new LenovoComputer() );
System.out.println( "用户付款了3000元" );
//调用其方法
c.sell( 3000 );
}
}

运行结果为:

2.动态代理。

  使用动态代理,代理实例时不需要开发人员去编写的,而是由相应

的处理程序在运行时动态产生一个字节码,这个字节码就是代理对象,加

载到JVM中。由于代理实例时在运行时才会动态产生,因此就叫做动态代理。

它和静态代理的区别就在于,静态代理的实例时人为编写的,并且编译器就

已经确定的。

在Java语言层面实现动态代理的机制有很多,我们只举JDK动态代理。

JDK动态代理(官方):

1.Proxy类,用于动态产生代理对象。

2.InvocationHandler接口,回调处理器,负责调用目标对象的行为,并实现

功能增强。

  JDK动态代理有一个特点,就是被代理的对象必须要有接口,如果没有接口,是实现不了

代理的。

举个例子:

Work接口:

package org2.proxy;

/**
* Created by Administrator on 2016/11/25.
* 编写一个接口
*/
public interface Work {
//接口中的抽象方法
public void work();
}

Teacher类实现Work接口: 

package org2.proxy;

/**
* Created by Administrator on 2016/11/25.
* 编写一个类实现该接口
*/
public class Teacher implements Work { //重写方法
@Override
public void work() {
System.out.println( "老师上课了" );
}
}

回调处理器:

package org2.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; /**
* Created by Administrator on 2016/11/25.
* 编写一个回调处理器
* 用于实现功能的增强,和调用目标对象的行为
*/
public class WorkInvocationHandler implements InvocationHandler { //这个对象就是被代理的对象
private Object target; //将被代理对象传入构造方法中
public WorkInvocationHandler( Object target ) {
this.target = target;
} //这个方法就是核心的回调方法
//它可以用来调用被代理对象的具体行为
//同时在调用目标对象方法之前或者之后做一些事情
//从而实现功能的增强
//参数一:代理对象,JDK运行时动态产生
//参数二:被代理对象需要执行的方法
//参数三:被代理对象执行的方法所需的参数
@Override
public Object invoke(Object proxy, Method method, Object[] args ) throws InvocationTargetException, IllegalAccessException {
//在调用目标对象行为之前做一些事情
System.out.println( "before:上课点名" ); //回调目标对象的具体行为
//回调方法之后一样有返回值,
//这个返回值就是目标对象的返回值
Object returnVal = method.invoke( target, args ); //在调用目标对象行为之后做一些事情
System.out.println( "after:布置作业" );
return returnVal;
}
}

Main方法:

package org2.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; /**
* Created by Administrator on 2016/11/25.
* main方法
*/
public class Main {
public static void main(String[] args) {
//创建需要被代理的对象
Teacher teacher = new Teacher();
//创建一个回调处理器,回调处理器会去调用teacher中的方法
InvocationHandler handler = new WorkInvocationHandler( teacher );
//使用Proxy类在运行时动态创建一个代理对象
//上面定义的回调处理器需要传递给这个Proxy类生成代理对象
//参数一:类加载器
//参数二:目标对象所实现的所有接口
//(由于JDK动态代理是基于接口来产生代理对象的,也就是创建出来的代理对象必须要实现一个接口)
//参数三:回调处理器
//newProxyInstance方法的返回值就是一个创建好的代理实例
Work work = ( Work )Proxy.newProxyInstance( Teacher.class.getClassLoader(), teacher.getClass().getInterfaces(), handler );
//调用其方法
work.work();
}
}

运行结果:

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

浅谈Java五大设计原则之代理模式的更多相关文章

  1. 浅谈Java五大设计原则之观察者模式

    定义一下观察者模式: 观察者模式又叫  发布-订阅  模式,定义的两个对象之间是一种一对多的强依赖关系,当一个对象的状态发生改变,所有依赖它的对象 将得到通知并自动更新(摘自Hand First). ...

  2. 浅谈Java五大设计原则之责任链模式

    首先我们得先定义一个责任链模式: 责任链模式是一种线性执行流程,多个对象都有机会去执行同一个任务,只是在执行过程中, 由于执行的权利和范围不一样,那么当自己不能处理此任务时,就必须将这个任务抛给下一个 ...

  3. 浅谈Java代理二:Cglib动态代理-MethodInterceptor

    浅谈Java代理二:Cglib动态代理-MethodInterceptor CGLib动态代理特点: 使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生 ...

  4. 浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance

    浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance java.lang.reflect.Proxy:该类用于动态生成代理类,只需传入目标接口.目标接口的类加载器以及Inv ...

  5. 浅谈java代理模式

    讲解java代理模式 目录 讲解java代理模式 何谓代理模式 静态代理 动态代理 JDK动态代理 CGLIB动态代理 何谓代理模式 代理模式,即Proxy Pattern,23种java常用设计模式 ...

  6. 浅谈PHP代码设计结构

    浅谈PHP代码设计结构 您的评价:       还行  收藏该经验       coding多年,各种代码日夜相伴,如何跟代码友好的相处,不光成为职业生涯的一种回应,也是编写者功力的直接显露. 如何看 ...

  7. 浅谈Android五大布局

    Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦.组件按照布局的要求依次排列,就组成了用户所看见的界面.Android的五大布局分别是LinearLay ...

  8. 浅谈Java的throw与throws

    转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...

  9. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

随机推荐

  1. qt 窗口动画

    窗口动画 编辑删除转载 2015-10-10 14:50:27 标签:qt渐变动画 一个应用程序通常包含多个动画,例如,你可能希望同时移动许多graphic items或者一个个按照串行的方式的移动他 ...

  2. linux service命令解析

      我们平时都会用service xxx start来启动某个进程,那么它背后究竟执行了什么? 其实service的绝对路径为/sbin/service ,打开这个文件cat /sbin/servic ...

  3. Eclipse窗口总是在最前的解决办法

    Eclipse窗口总是在最前的解决办法 状况: Eclipse在偶然的情况下,会莫名其妙地保持在窗口的最前面,一直保持在最前:然后alt + tab,或者鼠标点击其他窗口.想切换/激活其他窗口时,根本 ...

  4. angularJS配合bootstrap动态加载弹出提示内容

    1.bootstrp的弹出提示 bootstrap已经帮我们封装了非常好用的弹出提示Popover. http://v3.bootcss.com/javascript/#popovers 2.自定义p ...

  5. [译]学习IPython进行交互式计算和数据可视化(一)

    --学习IPython进行交互式Python编程.高性能数字计算和数据可视化 作者:Cyrille Rossant 译者:Tacey Wong 注:仅为个人翻译及学习,多有谬处,E文尚可的推荐阅读英文 ...

  6. ASP.NET MVC系列:为已有模型添加新的属性

    在模型类Movie中添加一个新的属性Rating

  7. easyui-datagrid自动合并行

    1.目标 1.1表格初始化完成后,已经自动合并好需要合并的行: 1.2当点击字段排序后,重新进行合并: 2.实现 2.1 引入插件 /** * author ____′↘夏悸 * create dat ...

  8. .Net(C#)最简单的邮件发送案例

    一.序言 刚开始接触邮件发送功能的时候,在网上找的资料都挺复杂的!对于新手入门有点难(至少对于本人来说,第一次接触的时候确实不容易).这里就写一段简单的邮箱发送代码,备忘,也给新手一个参考(相关类的字 ...

  9. 单元测试与Nunit的基本使用

    一.单元测试是什么 单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证.对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,C# ...

  10. [修正] Berlin 10.1 支持 iPhone 4 (iOS v7.x)

    原本在 Seattle 版本时,还能支持 iPhone 3GS (iOS v6.x), iPhone 4 (iOS v7.x),到了 Berlin 已不支持了,在用户的抱怨下,只好自己尝试去修正它,经 ...