您的位置:首页 > 编程语言 > Java开发

Spring对AOP的支持

2010-03-31 19:03 387 查看
面向切面编程是对面向对象编程的补充,AOP从动态的角度考虑程序结构,OOP将程序分解为各个层次的对象,而AOP将程序运行过程分解为各个切面。

AOP是Spring的一个关键组件,AOP框架是Spring IoC的完善和补充,使之成为更加有效的中间件,IoC容器(BeanFactory或者ApplicationContext)并不依赖于AoP框架,Spring AOP的目标好似提供与Spring IoC容器紧密结合的AOP框架,希望AOP框架与IoC容器完美结合。

AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,AOP面对程序运行中的各个步骤,以降低各步骤之间的耦合,从而提高步骤之间的隔离。

OOP是静态的抽象,它对实体的属性和行为进行抽象,从而获得清晰的单元,而AOP是动态的抽象,对应用执行过程的步骤进行抽象,从而获得各步骤的逻辑划分,AOP框架并不与特定的代码耦合,能够处理程序执行中特定点,而不是某个具体的程序。

AOP的两个特点:个步骤之间的良好隔离性,源代码无关性。

1.AOP中的概念

(1)切面:关注点的模块化,关注点可能横切多个对象;

(2)连接点:方法的调用

(3)处理:AOP在特定的连接点执行的动作,处理包括"around""before""throw",大部分框架以拦截器作为处理模型

(4)切入点:系列连接点的集合,确定处理触发的时机,AOP框架允许开发者自己定义切入点;

(5)引入:添加方法或字段到被处理的类,Spring允许引入新的接口到任何被处理的对象,可以使用一个引用,使任何对象实现IsModified接口,以此来简化缓存;

(6)目标对象:包含连接点的对象

(7)AOP代理:AOP框架创建的对象,包含处理,Spring中的AOP代理可以是JDK动态代理,也可以是CGLIB代理,前者为实现接口的目标对象的代理,后者为不实现接口的目标对象的代理。

2.AOP代理

AOP代理是AOP框架创建的对象,通常AOP代理可以是目标对象的替代品,而AOP代理提供比目标对象更为强大的功能,如,目标bean不是事物型的,而AOP代理包含目标bean的全部方法,而且这些方法经过加强,变成事务性方法,AOP代理是对目标对象的加强,在目标对象的基础上,增加属性和方法,提供更强大的功能。

切入点是可以触发处理的连接点的集合,切入点处加入的处理,使得目标对象的方法功能更强。AOP代理包装目标对象,在切入点出加入处理,使目标对象的方法功能更强。

Spring默认使用JDK动态代理实现AOP代理,主要用于代理接口,也可以使用CGLIB代理,实现类的代理,如果业务对象(目标bean)没有实现接口,默认使用CGLIB代理,面向接口编程时良好的习惯,尽量不要面向具体类编程,因此,业务对象通常应实现一个或者多个接口。

(a)定义业务对象实现的接口

public interface Dog {
public void info();
public void run();

}


(b)定义业务对象

public class DogImpl implements Dog {

@Override
public void info() {
// TODO Auto-generated method stub
System.out.println("I am a dog");

}

@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("I am running fast!!");
}

}


(c)定义通用的处理类,处理类没有与任何特定的类耦合,它可以处理所有的目标对象,java.lang.reflect下增加InvocationHandler接口,该接口是所有处理类的根接口。

处理类实现InvocationHandler接口,实现该接口必须实现invoke(Object proxy,Method method,Object[] args)方法,程序调用代理的目标方法时,自动变成调用invoke方法。

该接口并未与任何接口或类耦合,它完全是通用的,它的目标实例时Object类型,可以是任何的类型,在invoke方法内,对目标对象的info方法进行假期那个,通过method对象的invoke方法,可以完成目标对象的方法的调用。

package Agent;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyHandler implements InvocationHandler {

private Object target;
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
Object result = null;
if(method.getName().equals("info")){
System.out.println("Begin transaction...");
result = method.invoke(target, args);
System.out.println("Submit transaction...");
}else{
result = method.invoke(target, args);

}
return result;
}

public void setTarget(Object o){
this.target = o;
}

}


(d)代理工厂

package Agent;

import java.lang.reflect.Proxy;

import SpringBeans.DogImpl;

public class MyProxyFactory {
public static Object getProxy(Object object){
//代理的处理类
ProxyHandler handler = new ProxyHandler();
//将业务对象托付给代理操作
handler.setTarget(object);
//用来创建动态代理的ClassLoader对象,业务对象实现的接口列表,代理包含的处理实例
return Proxy.newProxyInstance(DogImpl.class.getClassLoader(), object.getClass().getInterfaces(), handler);

}

}


Proxy.newProxyInstance()方法通过接口数组动态创建代理类实例,接口数组通过object.getClass().getInterfaces()方法获得,创建的代理类是JVM在内存中动态创建,该类实现传入的接口数组的全部接口。

Dynamic Proxy要求被代理的必须是接口的实现类,否则无法构造相应的动态类,Spring对接口实现类采用Dynamic Proxy实现AOP,而对没有实现任何接口的类,通过CGLib实现AOP代理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: