Spring Aop 梳理
Aspect Oriented Programming 面向切面编程。解耦是程序员编码开发过程中一直追求的。AOP也是为了解耦所诞生。
具体思想是:定义一个切面,在切面的纵向定义处理方法,处理完成之后,回到横向业务流。
AOP 主要是利用代理模式的技术来实现的。
1、静态代理:就是设计模式中的proxy模式
a、业务接口
/**
* 抽象主题角色:声明了真实主题和代理主题的共同接口。
*
* @author Monkey
*
*/
public interface ITalk { public void talk(String msg); }
b、业务实现
/**
* 真实主题角色:定义真实的对象。
*
* @author Monkey
*
*/
public class PeopleTalk implements ITalk { public String username;
public String age; public PeopleTalk(String username, String age) {
this.username = username;
this.age = age;
} public void talk(String msg) {
System.out.println(msg + "!你好,我是" + username + ",我年龄是" + age);
} public String getName() {
return username;
} public void setName(String name) {
this.username = name;
} public String getAge() {
return age;
} public void setAge(String age) {
this.age = age;
} }
c、代理对象
/**
* 代理主题角色:内部包含对真实主题的引用,并且提供和真实主题角色相同的接口。
*
* @author Monkey
*
*/
public class TalkProxy implements ITalk { private ITalk talker; public TalkProxy(ITalk talker) {
// super();
this.talker = talker;
} public void talk(String msg) {
talker.talk(msg);
} public void talk(String msg, String singname) {
talker.talk(msg);
sing(singname);
} private void sing(String singname) {
System.out.println("唱歌:" + singname);
} }
d、测试
/**
* 代理测试类,使用代理
*
* @author Monkey
*
*/
public class ProxyPattern { public static void main(String[] args) {
// 不需要执行额外方法的。
ITalk people = new PeopleTalk("AOP", "18");
people.talk("No ProXY Test");
System.out.println("-----------------------------"); // 需要执行额外方法的(切面)
TalkProxy talker = new TalkProxy(people);
talker.talk("ProXY Test", "代理");
} }
从这段代码可以看出来,代理模式其实就是AOP的雏形。 上端代码中talk(String msg, String singname)是一个切面。在代理类中的sing(singname)方法是个后置处理方法。
这样就实现了,其他的辅助方法和业务方法的解耦。业务不需要专门去调用,而是走到talk方法,顺理成章的调用sing方法。
再从这段代码看:1、要实现代理方式,必须要定义接口。2、每个业务类,需要一个代理类。
2、动态代理:jdk1.5中提供,利用反射。实现InvocationHandler接口。
业务接口还是必须得,业务接口,业务类同上。
a、代理类
/**
* 动态代理类
*
* @author Monkey
*
*/
public class DynamicProxy implements InvocationHandler { /** 需要代理的目标类 */
private Object target; /**
* 写法固定,aop专用:绑定委托对象并返回一个代理类
*
* @param delegate
* @return
*/
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
} /**
* @param Object
* target:指被代理的对象。
* @param Method
* method:要调用的方法
* @param Object
* [] args:方法调用时所需要的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
// 切面之前执行
System.out.println("切面之前执行");
// 执行业务
result = method.invoke(target, args);
// 切面之后执行
System.out.println("切面之后执行");
return result;
} }
b、测试
/**
* 测试类
*
* @author Monkey
*
*/
public class Test { public static void main(String[] args) {
// 绑定代理,这种方式会在所有的方法都加上切面方法
ITalk iTalk = (ITalk) new DynamicProxy().bind(new PeopleTalk());
iTalk.talk("业务说明");
}
}
输出结果会是:
切面之前执行
people talk业务说法
切面之后执行
说明只要在业务调用方法切面之前,是可以动态的加入需要处理的方法。
从代码来看,如果再建立一个业务模块,也只需要一个代理类。ITalk iTalk = (ITalk) new DynamicProxy().bind(new PeopleTalk()); 将业务接口和业务类绑定到动态代理类。
但是这种方式:还是需要定义接口。
3、cglib
CGLIB是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强。采用的是继承的方式。不细说,看使用
a、业务类
/**
* 业务类
*
* @author Monkey
*
*/
public class PeopleTalk { public void talk(String msg) {
System.out.println("people talk" + msg);
} }
b、cglib代理类
/**
* 使用cglib动态代理
*
* @author Monkey
*
*/
public class CglibProxy implements MethodInterceptor { private Object target; /**
* 创建代理对象
*
* @param target
* @return
*/
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
} @Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object result = null;
System.out.println("事物开始");
result = methodProxy.invokeSuper(proxy, args);
System.out.println("事物结束");
return result;
} }
c、测试类
/**
* 测试类
*
* @author Monkey
*
*/
public class Test { public static void main(String[] args) {
PeopleTalk peopleTalk = (PeopleTalk) new CglibProxy().getInstance(new PeopleTalk());
peopleTalk.talk("业务方法");
peopleTalk.spreak("业务方法");
} }
最后输出结果:
事物开始
people talk业务方法
事物结束
事物开始
spreak chinese业务方法
事物结束
Spring Aop 梳理的更多相关文章
- Spring AOP梳理
一.Srping AOP AOP(Aspect Oriented Programming)解释为面向切面编程,何为切面,用刀把一块面包切成两半,刀切下去形成的面就叫切面,那么面向切面的就是形成切面的这 ...
- [转]彻底征服 Spring AOP 之 理论篇
基本知识 其实, 接触了这么久的 AOP, 我感觉, AOP 给人难以理解的一个关键点是它的概念比较多, 而且坑爹的是, 这些概念经过了中文翻译后, 变得面目全非, 相同的一个术语, 在不同的翻译下, ...
- [Spring框架]Spring AOP基础入门总结一.
前言:前面已经有两篇文章讲了Spring IOC/DI 以及 使用xml和注解两种方法开发的案例, 下面就来梳理一下Spring的另一核心AOP. 一, 什么是AOP 在软件业,AOP为Aspect ...
- 转载:Spring AOP (下)
昨天记录了Spring AOP学习的一部分(http://www.cnblogs.com/yanbincn/archive/2012/08/13/2635413.html),本来是想一口气梳理完的.但 ...
- (转)spring aop(下)
昨天记录了Spring AOP学习的一部分(http://www.cnblogs.com/yanbincn/archive/2012/08/13/2635413.html),本来是想一口气梳理完的.但 ...
- 彻底征服 Spring AOP 之 理论篇
基本知识 其实, 接触了这么久的 AOP, 我感觉, AOP 给人难以理解的一个关键点是它的概念比较多, 而且坑爹的是, 这些概念经过了中文翻译后, 变得面目全非, 相同的一个术语, 在不同的翻译下, ...
- Spring AOP 学习例子
http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example 工作忙,时间紧,不过事情再多,学习是必须的.记得以前的部门老大 ...
- Spring AOP 知识点入门
一.基本知识点 1.AOP概念 AOP(Aspect-Oriented Programming), 即 面向切面编程, 它与 OOP( Object-Oriented Programming, 面向对 ...
- Spring AOP概述
一.AOP的基本概念: 首先先给出一段比较专业的术语: 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的 ...
随机推荐
- JQuery实战---窗口效果
在前面的相关博文中,小编对jquery的相关知识进行了简单的总结,关于jquery的很多小的知识点,都需要我们自己去动手和实践,一行行代码都需要我们自己亲自动手去敲,今天我们继续来学习jquery的相 ...
- android studio——Failed to set up SDK
最近使用android studio ,在IDE里面使用Gradle构建的时候,一直出现构建失败,失败信息显示Failed to set up SDK.然后 提示无法找到andriod-14平台,我更 ...
- 使用lrucache和diskLrucache实现照片墙
其实,在真正的项目实战当中如果仅仅是使用硬盘缓存的话,程序是有明显短板的.而如果只使用内存缓存的话,程序当然也会有很大的缺陷.因此,一个优秀的程序必然会将内存缓存和硬盘缓存结合到一起使用,那么本篇文章 ...
- java wait和notify及 synchronized sleep 总结
java 中线程我一直弄不清线程锁等 所以写了一些例子验证看法: 在这之前先看下API中wait中的解释: wait:方法来之java.lang.Objetc 方法翻译:在其他线程调用此对象的 not ...
- A*寻路算法入门(七)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...
- pig强制转换(字符到整数):首位0怎么处理,‘01’到1的转化,
pig支持的类型转换(cast) Pig Latin supports casts as shown in this table. from / to bag tuple map int long f ...
- 抓包工具Fidder详解
第一步:下载神器Fiddler,下载链接: http://fiddler2.com/get-fiddler 下载完成之后,傻瓜式的安装一下了! 现在这个下载链接失效了,可以百度下载 第二步:设置Fid ...
- sublimeText3使用记录
sublime确实是神器,最近学习了一下,做个记录 1.下载 http://www.sublimetext.com/3 选择对应的版本安装即可(我的是win10 64位机) 2.个人配置 2.1.默认 ...
- MPLSVPN 命令集
载请标明出处:http://blog.csdn.net/sk719887916,作者:skay 读懂下面配置命令需要有一定的TCP/IP,路由协议基础,现在直接上关键VPN命令. router ...
- Dynamics CRM2011 隐藏sub-grid 新建项和添加现有项按钮
在CRM2011中ribbon区的自定义按钮可以通过工具例如RibbonEditor或者RibbonWorkbench进行配置包括action.display等等,但是系统级别的按钮是不能进行编辑的, ...