最近想了解下aop,读了些入门级的文章,理解如下:
其实AOP的意思就是面向切面编程.
OO注重的是我们解决问题的方法(封装成Method),而AOP注重的是许多[color=red]解决问题的方法中的共同点,是对OO思想的一种补充[/color]!
还是拿人家经常举的一个例子讲解一下吧:
比如说,我们现在要开发的一个应用里面有很多的业务方法,但是,我们现在要对这个方法的执行做全面监控,或部分监控.也许我们就会在要一些方法前去加上一条日志记录,
我们写个例子看看我们最简单的解决方案
代码如下:
TargetService和TargetBean是目标业务接口和目标业务实现类,为最终需要执行的业务逻辑
public interface TargetService
{
public void A();
public void B();
}
实现类 TargetBean
public class TargetBean implements TargetService
{
public void A()
{
System.out.println(“execute method A”);
}
public void B()
{
System.out.println(“execute method B”);
}
}
ProxyOperationService和ProxyOperationBean是代理额外操作接口和代理额外操作实现类,为代理在目标对象上封装的一些操作,增强目标对象的功能。
public interface ProxyOperationService
{
public void begin(Method method);
public void end(Method method);
}
public class ProxyOperationBean implements ProxyOperationService
{
@Override
public void begin(Method method)
{
System.out.println(method.getName() + ” method begin”);
}
@Override
public void end(Method method)
{
System.out.println(method.getName() + ” method end”);
}
}
public class ProxyBean implements InvocationHandler
{
//最终要实现的目标对象
private Object targetObj;
//代理所作的额外操作对象
private Object proxyOperationObj;
//动态生成方法被处理过后的代理对象 (写法固定)
public Object bind(Object obj, Object proxyOperObj)
{
targetObj = obj;
proxyOperationObj = proxyOperObj;
Class cls = targetObj.getClass();
return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), this);
}
@Override
//要处理的对象中的每个方法会被此方法送去JVM调用,也就是说,要处理的对象的方法只能通过此方法调用
//此方法是动态的,不是手动调用的
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable
{
Object obj = null;
try
{
//反射得到代理所作的额外操作对象
Class proxyOperClass = proxyOperationObj.getClass();
//反射得到begin方法
Method startMethod = proxyOperClass.getDeclaredMethod(“begin”, Method.class);
//反射执行begin方法
startMethod.invoke(proxyOperationObj, method);
obj = method.invoke(targetObj, args);
//反射得到end方法
Method endMethod = proxyOperClass.getDeclaredMethod(“end”, Method.class);
//反射执行end方法
endMethod.invoke(proxyOperationObj, method);
}
catch(Exception e)
{}
return obj;
}
public static void main(String[] args)
{
//此处必须使用目标接口,使用目标实现类会产生类转换错误
TargetService tBean = (TargetService)new ProxyBean().bind(new TargetBean(), new ProxyOperationBean());
tBean.A();
tBean.B();
}
}
aop实现原理的核心是动态代理,根据代理类来动态产生目标对象,在调用目标对象方法时添加些共同的功能。
如果我们不想让所有方法都被日志记录,我们应该怎么去解藕呢.?
我的想法是在代理对象的public Object invoke(Object proxy, Method method, Object[] args)方法里面加上个if(),对传进来的method的名字进行判断,判断的条件存在XML里面.这样我们就可以配置文件时行解藕了.如果有兴趣的朋友可以把操作者,被代理者,都通过配置文件进行配置 ,那么就可以写一个简单的SpringAOP框架了.