Spring框架AOP
2016-03-30 23:24
148 查看
面向对象的编程(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;
}
使用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;
}
相关文章推荐
- Java实现排序算法1:5种易理解的算法
- [leetcode-332]Reconstruct Itinerary(java)
- Java设计模式之单例模式
- Spring JDBC学习笔记(2):JdbcTemplate的增强版NamedParameterJdbcTemplate
- 将Windows文件路径转换为java中可识别的文件路径
- Java泛型深入理解
- Java 异常
- java中Comparator接口
- java 垃圾回收机制
- java SE基础(Map接口及其实现)
- java.lang.OutOfMemoryError: PermGen space及其解决方法
- spring data jpa 操作JPA 2.0原生api
- Java 多线程实现的三种方法,附两个线程执行不同的输出
- Java SE 疑难点记录
- Java 1.7 ReentrantReadWriteLock源码解析
- Java并发编程:阻塞队列
- java学习之迭代器浅谈
- Struts1与Struts2原理 区别 详解 汇总
- 学习javaEE每一天2016.3.30
- JavaMail发送邮件