AOP概述
AOP全名 Aspect-Oriented Programming ,中文直译为面向切面(方面)编程,当前已经成为一种比较成熟的编程思想,可以用来很好的解决应用系统中分布于各个模块交叉关注点的问题。如事务处理、安全检查、缓存和对象管理等,已经成为一种非常适用的解决方案。
1.代理机制
代理机制主要有两种:静态代理(Static Proxy)和动态代理(Dynamic Proxy)
1.1 静态代理
1.1.1 定义代理接口;
public interface IComponent {
public void business1();
public void business2();
public void business3();
}
1.1.2 编写代理对象;
public class ProxyComponent implements IComponent {
private IComponent component;
public ProxyComponent(IComponent component){
this.component = component;
}
@Override
public void business1() {
validateUser();
this.component.business1();
}
@Override
public void business2() {
validateUser();
this.component.business2();
}
@Override
public void business3() {
validateUser();
this.component.business3();
}
private void validateUser(){
System.out.println( "验证用户信息............");
}
}
1.1.3编写被代理对象
public class Component implements IComponent {
public void business1(){
System.out.println( "业务1");
}
public void business2(){
System.out.println( "业务2");
}
public void business3(){
System.out.println( "业务3");
}
}
1.1.4编写测试类
public class TestStaticProxy {
public static void main( String[] args) {
IComponent component = new ProxyComponent( new Component());
component.business1();
component.business2();
component.business3();
}
}
1.2 动态代理
结合静态代理的实现机制,抽象出一个泛类代理,也就是说,不用依赖任何代理对象的代理实现,通过调用java.lang.reflect.InvocationHandler接口来实现一个处理被代理对象的类来完成代理,具体以一个实例来讲解。
1.2.1编写代理对象类;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxy implements InvocationHandler {
private Object obj;
public Object bind(Object obj){
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
try{
this.validateUser();
result = method.invoke(obj, args);
} catch( Exception e){
e.printStackTrace();
}
return result;
}
private void validateUser(){
System.out.println( "验证用户信息............");
}
}
1.2.2 编写动态代理测试类;
public class TestDynamicProxy {
public static void main( String[] args) {
DynamicProxy dp = new DynamicProxy();
IComponent component = (IComponent) dp.bind( new Component());
component.business1();
component.business2();
component.business3();
}
}
2.AOP常用术语
2.1.切面(Aspect)
切处理包括属性和方法外,同时还包括切入点和增强等。另外切面中还可以给一个现存的类添加属性和构造器,制定一个实现类某个接口和继承某一个类等。
< aop:pointcut id= "somePointcut" expression= "execution(*Component.*(..))" />
< aop:after-returning pointcut-ref= "" method= "" />
< /aop:aspect>
2.2.连接点(Join Point)
连接点是指程序中的某一个点。连接点分的非常细致,如一个方法、一个属性、一条语句、对象加载和构造器等都可以作为连接点。AspecJ中的连接点主要有下面的几种形式.
方法调用、 方法执行、 构造函数调用、
构造函数执行、静态初始化部分执行、 对象预初始化、 对象初始化、 属性引用、 属性设置、 异常执行、 通知执行;
2.3. 切入点(Pointcuts)
切入点指一个或多个点的集合,可以理解成一个点的集合。切入点的描述比较具体,而且一般会跟连接点上下文环境结合。
2.4.增强或通知(Advice)
通知(Advice)里面定义了切面中的实际逻辑(即实现),比如日志的写入的实际代码,或是安全检查的实际代码。换一种说法,增强(Advice)是指在定义好的切入点处,所要执行的程序代码。
一般情况下,通知(增强)主要有前通知、后通知和环绕通知3中基本类型。
前置通知:
是指在连接点之前,先执行的增强的代码;
是指会在目标对象的方法执行之前被调用;
后通知:
是指在连接点执行后,再执行增强中的代码。后增强一般分为连接点正常返回增强及连接点异常返回增强等类型。
是在指定的程序片段后执行的一些服务;
环绕通知:
是一种功能强大的增强,可以自由地改变程序的流程,连接点返回值等。
就是在指定的程序前后均执行相关的服务;也相当于前置通知和后置通知的结合;
2.5.拦截器
拦截器是用来实现对连接点进行拦截,从而在连接点前或后加入自定义的切面模块功能。
2.6.目标对象
指在基于拦截器机制实现的AOP框架中,位于拦截器链上最末端的对象实例。
2.7.AOP代理(proxy)
AOP代理是指在基于拦截器机制实现的AOP框架中,实际业务对象的代理对象。