Spring框架AOP

来源:互联网 发布:php.ini safe mode 编辑:程序博客网 时间:2024/05/22 16:23
 面向对象的编程(OOP)方法是在面向过程的编程方法基础上进行的改进,而面向方面编程(AOP)方法又是在面向对象编程(OOP)方法的基础上进行改进而来的一种创新的软件开发方法。AOP和OOP虽然在字面上十分相似,但是却是面向不同领域的两种设计思想。OOP(面向对象编程)针对问题领域中以及业务处理过程中存在的实体及其属性和操作进行抽象和封装,面向对象的核心概念是纵向结构的,其目的是获得更加清晰高效的逻辑单元划分;而AOP则是针对业务处理过程中的切面进行提取,例如,某一个操作在各个模块中都有涉及,这个操作就可以看成“横切”存在于系统当中。在许多情况下,这些操作都是与业务逻辑相关性不强或者不属于逻辑操作的必须部分,而面向对象的方法很难对这种情况做出处理。AOP则将这些操作与业务逻辑分离,使程序员在编写程序时可以专注于业务逻辑的处理,而利用AOP将贯穿于各个模块间的横切关注点自动耦合进来。AOP所面对的是处理过程中的某个步骤或阶段,对不同的阶段领域加以隔离,已获得逻辑过程中各部分之间低耦合性的隔离效果,其与面向方面编程在目标上有着本质的差异。AOP的核心思想就是将应用程序中的业务逻辑处理部分同对其提供支持的通用服务,即所谓的“横切关注点”进行分离,这些“横切关注点”贯穿了程序中的多个纵向模块的需求。

  使用AOP机制进行开发,首先要对方面进行了解,将需求分解成一般关注点和横切关注点,即将核心模块级的关注点和系统级的横切关注点分离;然后各自独立的实现这些关注点;最后用工具将业务逻辑代码和横切关注点代码编织到一起,形成最终的程序。通过面向方面的编程可以减少编码时间和重复。

代码如下:

@Aspect//声明为一个切面
public class LogAspect {

/**
*定义一个前置通知(before通知)
*/
@Before(value="execution(* com.lovo.service.impl.*ServiceImpl.*(..))")
public void beforeAdvice(JoinPoint jp){
Object target = jp.getTarget();//获取目标对象
Object proxy =  jp.getThis();//获取目标对象的代理对象
String method = jp.getSignature().getName();//获取目标方法
System.out.println("目标对象是:"+target+"" 
+ "---------目标方法是:"+method 
+ "---------代理对象是:"+proxy);
System.out.println("我是前置通知,我可以在方法执行之前进行一些操作!");
}


/**
* 定义一个后置返回通知(afterReturning通知)
* 该通知执行在目标方法,返回之后
 
@AfterReturning(returning="rvt",value="execution(* com.lovo.service.impl.*ServiceImpl.*(..))")
public void afterReturningAdvice(Object rvt){
System.out.println("我是后置返回通知,我可以在方法执行之后获取到目标方法的返回");
System.out.println(rvt);

}*/

/**
* 定义一个后置异常通知(afterThrowing)
* 该通知需要注意的是:被通知对象,一定不能自己抓捕异常,而应该向上继续抛
 
@AfterThrowing(throwing="ex",value="execution(* com.lovo.service.impl.*ServiceImpl.*(..))")
public void afterThrowingAdvice(Throwable ex){
System.out.println("我是后置异常通知,我可以在方法抛出异常之后,获取到目标方法的异常");
System.out.println("目标方法抛出的异常是:"+ex);
}*/

/**
* 定义一个后置通知(after)
 
@After(value="execution(* com.lovo.service.impl.*ServiceImpl.*(..))")
public void afterAdvice(){
System.out.println("我是后置通知,你有没有返回,抛不抛异常,我都要执行!等同于finally");
}*/

/**
* 定义一个环绕通知(around)
* 固定参数ProceedingJoinPoint jp,程序连接点
* @throws Throwable 
 
@Around(value="execution(* com.lovo.service.impl.*ServiceImpl.*(..))")
public Object arountAdvice(ProceedingJoinPoint jp) throws Throwable{

System.out.println("目标方法执行之前,我可以修改目标方法对应的参数!");
UserInfoT user = new UserInfoT("美女,你好啊!", "打开你的心扉呗!");
Object[] objts = jp.getArgs();//可以获取到目标方法的所有参数
objts[0] = user;
SqlSession session = DBUtil.getSession();
Object ret = null;
try {
ret = jp.proceed(objts);//调用目标方法的执行
session.commit();
} catch (Exception e) {
// TODO: handle exception
session.rollback();
}
//我接下来,可以修改目标方法的返回值,本来应该是3,但我修改为2
ret = 2;
return ret;
}


0 0