标签:
在传统OOP编程里以对象为核心,整个软件系统由系统相互依赖的对象组成,而这些对象将被抽象一个一个的类,并允许使用类继承来管理类与类之间一般到特殊的关系,随着软件规模的增大,应用的逐渐升级,慢慢出现了一些OOP很难解决的问题。 现在假设系统中有三段完全相似的代码,这些代码通常会采用“复制”,“粘贴”方式来完成,通过这种方式产生的代码,如果有一天,代码需要修改,那么就要打开涉及这些代码相似的三个地方,逐一修改……,那如果是100,1000个相似的地方呢?为了解决这个问题,我们通常是采用将重复代码部分定义成一个方法,然后再三个代码段中调用该方法即可,如果需要修改代码,只需要修改定义的方法即可,不管整个系统中有多少地方调用了该方法,程序都无须修改这些地方,只需修改被调用的方法即可----通过这种方式,大大降低了软件后期维护的复杂性。AOP专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题,在JavaEE应用中,常常通过AOP来处理一些具有横切性质的系统级服务,如事务管理、安全管理、缓存、对象池管理等,AOP已经成为一种非常常见的解决方案。
在工作面试的时候可能遇到的问题:AOP在你的项目中哪些地方可以使用到?
答:事务管理 操作日志 缓存
AOP中常用的术语:
7、代理对象(proxy object)
为目标对象增加新功能从而产生的一个新的对象称为代理对象.负责调用拦截器和目标对象的方法.
8 、引入(Instroduction)
引入允许你为已存在类添加新方法和属性。
前置通知(@Before) 后置通知(@AfterReturning、@After)异常通知(@AfterThrowing)环绕通知(@Around)
1 package com.cy.aspect; 2 3 import org.aspectj.lang.JoinPoint; 4 import org.aspectj.lang.ProceedingJoinPoint; 5 import org.aspectj.lang.annotation.After; 6 import org.aspectj.lang.annotation.AfterReturning; 7 import org.aspectj.lang.annotation.AfterThrowing; 8 import org.aspectj.lang.annotation.Around; 9 import org.aspectj.lang.annotation.Aspect; 10 import org.aspectj.lang.annotation.Before; 11 12 import com.cy.entitys.UserInfoT; 13 14 @Aspect// 声明一个日志切面 15 public class LogAspectJ { 16 17 //第一个*代表目标方法的访问修饰符,如:public,private…… 18 //*Impl 这里的*代表着:所有以Impl结尾的JAVA类 19 //*(..) 这里的*代表着:JAVA类内部的方法名 20 /** 21 * 定义一个前置通知(before) 22 * @param jp 连接点 23 */ 24 @Before("execution(* com.lovo.service.impl.*Impl.*(..))") 25 public void beforeAdvice(JoinPoint jp){ 26 System.out.println("before通知的目标对象:" + jp.getTarget()); 27 System.out.println("before通知的目标方法:" + jp.getSignature().getName()); 28 29 } 30 31 /** 32 * 定义一个后置通知(afterReturning),只有目标方法正常执行的情况下,才会被通知 33 * @param jp 连接点 34 * @param rvt 目标方法的返回 35 */ 36 //returning="rvt" 指定一个返回的形参名,通知方法可以通过该形参名来获取目标方法的返回值 37 //pointcut 用于指定该切入点对应的切入表达式 38 @AfterReturning(returning="rvt",pointcut="execution(* com.lovo.service.impl.*Impl.*(..))") 39 public void afterReturningAdvice(JoinPoint jp,Object rvt){ 40 System.out.println("afterReturning通知的目标对象:" + jp.getTarget()); 41 System.out.println("afterReturning通知的目标方法:" + jp.getSignature().getName()); 42 System.out.println("afterReturning通知的目标方法的返回值:"+ rvt); 43 UserInfoT user = (UserInfoT) rvt; 44 System.out.println("afterReturning具体返回的值是:" + user.getName()); 45 } 46 47 48 49 /** 50 * 定义一个异常通知 51 * @param jp 连接点 52 * @param tx 目标方法所抛出的异常 53 */ 54 55 56 //throwing="tx" 指定一个返回异常的形参名,通知方法可以通过该形参名来获取目标方法返回的异常信息 // Integer.valueOf("asdfasdf"); 57 //pointcut 用于指定该切入点对应的切入表达式 58 @AfterThrowing(throwing="tx",pointcut="execution(* com.lovo.service.impl.*Impl.*(..))") 59 public void afterThrowingAdvice(JoinPoint jp,Throwable tx){ 60 System.out.println("afterThrowing通知的目标对象:" + jp.getTarget()); 61 System.out.println("afterThrowing通知的目标方法:" + jp.getSignature().getName()); 62 System.out.println("afterThrowing通知目标方法抛出的异常:" + tx); 63 } 64 65 /** 66 * 定义一个后置通知,无论目标方法是否正常运行,都会被通知到 67 * @param jp 连接点 68 */ 69 70 @After("execution(* com.lovo.service.impl.*Impl.*(..))") 71 public void afterAdvice(JoinPoint jp){ 72 System.out.println("after通知的目标对象:" + jp.getTarget()); 73 System.out.println("after通知的目标方法:" + jp.getSignature().getName()); 74 } 75 76 /** 77 * 定义一个环绕通知,该通知可以认为是:before + afterReturning 78 * 有2个特点:1、可以控制目标方法何时执行 2、可以修改目标方法的参数和返回 79 * @param jp 第一个参数必须是ProceedingJoinPoint 80 * @return 81 * @throws Throwable 82 */ 83 @Around("execution(* com.lovo.service.impl.*Impl.*(..))") 84 public Object aroundAdvice(ProceedingJoinPoint jp) throws Throwable{ 85 86 UserInfoT user = new UserInfoT(); 87 user.setId(Long.valueOf(2)); 88 user.setName("小丽变胖了"); 89 user.setSex(1); 90 91 Object[] params = jp.getArgs();//获取目标方法的参数 92 System.out.println("around通知目标方法获取的参数:" + params); 93 94 Object ret = jp.proceed(new Object[]{user});//显示调用该方法,控制目标方法执行 95 if(ret == null){ 96 return user; 97 } 98 return ret; 99 } 100 101 }
测试
package com.cy.action; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.cy.entitys.Configer; import com.cy.entitys.UserInfoT; import com.cy.service.IUserService; public class TestAction { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); /** */ IUserService service = (IUserService) ac.getBean("userServiceImpl"); UserInfoT user = new UserInfoT(); user.setName("小黄"); System.out.println("saveUser======================================"); service.saveUser(user); System.out.println("updateUser======================================"); service.updateUser(user); System.out.println("deleteUser======================================"); service.deleteUser(user); System.out.println("getUser======================================"); service.getUser(UserInfoT.class, Long.valueOf(1)); System.out.println("testException======================================"); service.testException(); } }
结果:
标签:
原文地址:http://www.cnblogs.com/hellokitty1/p/5071235.html