通过XML注释使用AOP
参考以下
http://blog.csdn.net/xiaoxian8023/article/details/17258933
1:添加aspectj的支持
1 <dependency> 2 <groupId>org.aspectj</groupId> 3 <artifactId>aspectjrt</artifactId> 4 <version>1.8.1</version> 5 </dependency> 6 <dependency> 7 <groupId>org.aspectj</groupId> 8 <artifactId>aspectjweaver</artifactId> 9 <version>1.8.1</version> 10 </dependency>
2:User类和UserDao类
1 public class User { 2 private String name; 3 public User(String name) { 4 this.name = name; 5 } 6 public String getName() { 7 return name; 8 } 9 public void setName(String name) { 10 this.name = name; 11 } 12 }
1 public interface UserDao { 2 public User findUserById(int id); 3 } 4 5 public class UserDaoImpl implements UserDao { 6 public User findUserById(int id) { 7 if(id < 0) { 8 throw new IllegalArgumentException("用户id不能小于0"); 9 } 10 return new User("zang"); 11 } 12 }
3:客户端代码
public class SpringTest { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao)ac.getBean("userDao"); //可以查找张三 userDao.findUserById(1); System.out.println("==================="); try { // 查不到数据,会抛异常,异常会被AfterThrowingAdvice捕获 userDao.findUserById(-1); } catch (IllegalArgumentException e) { } } }
4:在applicationContext.xml中进行aop配置
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans 3 xmlns="http://www.springframework.org/schema/beans" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xmlns:p="http://www.springframework.org/schema/p" 7 xmlns:context="http://www.springframework.org/schema/context" 8 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 9 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 10 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> 11 12 <context:component-scan base-package="test"/> 13 14 <bean id="userDao" class="dao.UserDaoImpl"></bean> 15 16 <bean id="xmlAspect" class="aspect.XMLAspect"></bean> 17 18 <aop:config> 19 <aop:aspect id="aspect" ref="xmlAspect"> 20 <!-- 定义切入点,一个切入点可能横切多个业务组件 --> 21 <aop:pointcut expression="execution(* dao.*.find*(..))" id="pointcut"/> 22 23 <!-- 定义切入点上的增强处理 --> 24 <aop:before method="doBefore" pointcut-ref="pointcut"/> 25 <aop:around method="doAround" pointcut-ref="pointcut"/> 26 <aop:after method="doAfter" pointcut-ref="pointcut"/> 27 <aop:after-returning method="doAfterReturning" pointcut-ref="pointcut" returning="rObj"/> 28 <aop:after-throwing method="doAfterThrowing" pointcut-ref="pointcut" throwing="ex"/> 29 30 </aop:aspect> 31 </aop:config> 32 33 34 </beans>
其中execution的规则如下图
5:XMLAspect.java
1 public class XMLAspect { 2 private void doBefore(JoinPoint joinPoint) { 3 } 4 5 private Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { 6 Object retVal = joinPoint.proceed(); 7 return retVal; 8 } 9 10 private void doAfter(JoinPoint joinPoint) { 11 } 12 13 private void doAfterReturning(JoinPoint joinPoint,Object rObj) { 14 } 15 16 private void doAfterThrowing(JoinPoint joinPoint,Throwable ex) { 17 } 18 }
a.doBefore
1 private void doBefore(JoinPoint joinPoint) { 2 System.out.println("-----doBefore().invoke-----"); 3 4 Signature signature = joinPoint.getSignature(); 5 System.out.println("DeclaringType:" + signature.getDeclaringType()); 6 System.out.println("DeclaringTypeName:" + signature.getDeclaringTypeName()); 7 System.out.println("Modifiers:" + signature.getModifiers()); 8 System.out.println("Name:" + signature.getName()); 9 System.out.println("LongString:" + signature.toLongString()); 10 System.out.println("ShortString:" + signature.toShortString()); 11 12 for (int i = 0; i < joinPoint.getArgs().length; i++) { 13 Object arg = joinPoint.getArgs()[i]; 14 if(null != arg) { 15 System.out.println("Args:" + arg.toString()); 16 } 17 } 18 19 20 System.out.println("-----End of doBefore()------"); 21 }
结果
b.doAround
1 private Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { 2 System.out.println("-----doAround().invoke-----"); 3 System.out.println(" 此处可以做类似于Before Advice的事情"); 4 5 //调用核心逻辑 6 Object retVal = joinPoint.proceed(); 7 System.out.println(retVal.getClass()); 8 User user = (User)retVal; 9 System.out.println(user.getName()); 10 11 System.out.println(" 此处可以做类似于After Advice的事情"); 12 System.out.println("-----End of doAround()------"); 13 return retVal; 14 }
结果
c.doAfter
1 private void doAfter(JoinPoint joinPoint) { 2 System.out.println("-----doAfter().invoke-----"); 3 System.out.println(" 此处意在执行核心业务逻辑之后,做一些日志记录操作等等"); 4 System.out.println(" 可通过joinPoint来获取所需要的内容"); 5 System.out.println("-----End of doAfter()------"); 6 }
d.doAfterReturning
1 private void doAfterReturning(JoinPoint joinPoint,Object rObj) { 2 System.out.println("-----doAfterReturning().invoke-----"); 3 4 User user = (User)rObj; 5 System.out.println(user.getName()); 6 7 Signature signature = joinPoint.getSignature(); 8 System.out.println("DeclaringType:" + signature.getDeclaringType()); 9 System.out.println("DeclaringTypeName:" + signature.getDeclaringTypeName()); 10 System.out.println("Modifiers:" + signature.getModifiers()); 11 System.out.println("Name:" + signature.getName()); 12 System.out.println("LongString:" + signature.toLongString()); 13 System.out.println("ShortString:" + signature.toShortString()); 14 15 for (int i = 0; i < joinPoint.getArgs().length; i++) { 16 Object arg = joinPoint.getArgs()[i]; 17 if(null != arg) { 18 System.out.println("Args:" + arg.toString()); 19 } 20 } 21 22 System.out.println("-----End of doAfterReturning()------"); 23 }
结果
通过JoinPoint和返回参数我们可以得到类运行时的所有相关信息,如通过方法名我们可以鉴别出是insert, update还是delete操作,针对不同的操作实现不同的处理方法,如调用缓存的add(),remove(),refresh()方法。我们还可以获取方法的调用参数及返回值,这极大的方便了我们对原业务逻辑的AOP处理。
e.doAfterThrowing
1 private void doAfterThrowing(JoinPoint joinPoint,Throwable ex) { 2 System.out.println("-----doThrowing().invoke-----"); 3 System.out.println(" 错误信息:"+ex.getMessage()); 4 System.out.println(" 此处意在执行核心业务逻辑出错时,捕获异常,并可做一些日志记录操作等等"); 5 System.out.println(" 可通过joinPoint来获取所需要的内容"); 6 System.out.println("-----End of doThrowing()------"); 7 }
结果
通过注解使用AOP
参考以下两篇博文