Spring2.0技术手册笔记——AOP_1_AOP概念与简单实现

Ioc之前看了一些书籍,有写概念,而AOP则基本没什么概念。感觉比较深奥,就先从这里开刀。不过看了看,感觉其实就那么回事。
一般情况下,一个方法里面除了完成业务外,肯定会加入一些其他多余的东西。。。。log(这个东西可能国外用得比较多,国内可能有这个习惯的人不多,我新手,肯定没这个习惯了。。。。),安全检查(这个应该是到处可见)。这样的话,这个方法就不‘纯’了。如果哪天你要把这写多余的东西去掉,那就要一个方法一个方法的去找。会累死人的。AOP就为解决这个问题的。
先看代码(代码都为技术手册实例,简单明了!)。
最原始也是最快速的给方法添加log的方法就像这样写。

import java.util.logging.Level;
import java.util.logging.Logger;

/*A normal java Class which will be
compared with a Class using AOP*/

public class NormalClass {
private Logger log = Logger.getLogger(this.getClass().getName());

public void hello(String name){
//log before print
log.log(Level.INFO,"hello method starts....");
//print
System.out.println("Hello," + name);
//log after print
log.log(Level.INFO,"hello method ends....");
}
}

假如100个方法都要加log,重复代码可想而知了。(英文注释自己写的,书写水平很烂,阅读水平一般,欢迎拍砖。。。。)
下面是以静态代理来实现最简单的aop。首先,定义个接口。实现类和代理类都实现此接口。

public interface SayHello {
void hello(String hello);
}

然后是实现类,里面就是最简单的业务处理---打印。

import staticproxy.inter.SayHello;

public class SayHelloImpl implements SayHello{

@Override
public void hello(String name) {
System.out.println("Hello," + name);
}

}

接着是代理类,代理类里添加log。

import java.util.logging.Level;
import java.util.logging.Logger;

import staticproxy.inter.SayHello;

public class SayHelloImplProxy implements SayHello {

private SayHello say;
private Logger log ;

public SayHelloImplProxy(SayHello say){
this.say = say;
log = Logger.getLogger(this.say.getClass().getName());
}

@Override
public void hello(String name) {
log.log(Level.INFO,"hello method starts....");
this.say.hello(name);
log.log(Level.INFO,"hello method ends....");
}

}

测试一下。

import dynamicproxy.LogHandler;

import staticproxy.SayHelloImpl;
import staticproxy.SayHelloImplProxy;
import staticproxy.inter.SayHello;
import normal.NormalClass;


public class Test {
public static void main(String[] args){
//Test normal.NormalClass
NormalClass nor = new NormalClass();
nor.hello("Ivan");

//Test staticproxy.SayHelloImpl
SayHello say = new SayHelloImplProxy(new SayHelloImpl());
say.hello("Ivan");

}
}

两个输出应该是一样的。这样就把业务和log分开了。这是代理模式的简单体现,应该很简单。不过缺点显而易见,每个类都得有个代理类。
于是就有了动态代理。直接实现java.lang.reflect.InvocationHandler接口即可。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LogHandler implements InvocationHandler {

private Logger log = Logger.getLogger(this.getClass().getName());
private Object delegate;

public Object bind(Object delegate) {
this.delegate = delegate;
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
delegate.getClass().getInterfaces(), this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object res = null;

log(method + " method starts....");
res = method.invoke(delegate, args);
log.log(Level.INFO,method + " method ends....");

return res;
}

private void log(String message) {
log.log(Level.INFO,message);
}

}

看起来好像挺复杂,其实和静态代理一样。其中的bind就相当于静态代理的构造方法。然后在调用时,会自动的调用invoke方法,在invoke方法里添加了log。
其他代码和静态代理的一模一样。不重复。
这样的话,你想在哪个方法里添加log,只要bind那个类就可以了。
这就是AOP了,没什么深奥的。就实现方法有区别而已。Spring里的AOP就是用动态代理实现的。

下面通过上面的代码解释几个AOP的名词。
1.Cross-cutting concern(直译应该叫“横切关注点”)
我理解的就是,需要以AOP来处理的东东。像log,安全检查这些。
2.Aspect(方面)
就是对于那些横切关注点所编写的类。如LogHandler。
3.Advice(原意“忠告”,感觉莫名其妙。)
可以理解为,在Aspect里面,实现的Cross-cutting concern的具体方法.如Loghandler里的invoke方法。
4.Joinpoint
Advice被执行的那个时机。(感觉比较抽象。保留意见。)
5.Pointcut
可以理解为Joinpoint执行的条件,符合Pointcut的Joinpoint才执行。
6.Target
简单理解为被代理的那个对象。如SayHelloImpl。
7.Introduction
给一个已编写或编译玩的类,在执行期间动态地加入一些方法或行为,而不修改或新增任何一行程序代码。(不解其意。。。。不是不懂他说的意思,而是不解,他说的是Introduction这个东东的功能还是什么。)
8.Proxy(代理)
。。。。
9.Weave(编织,组合,编排)
Advice被应用至对象之上的过程称之为Weave。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值