前言
基于上篇介绍玩AOP的相关概念以及通知类型,我们继续了解AOP的几种使用方法.
- 经典的基于代理的AOP
- @AspectJ注解驱动的切面
- 纯POJO切面(纯粹通过aop:fonfig标签配置)
- 注入式AspectJ切面
AOP常用的实现方式有两种,
1、采用声明的方式来实现(基于XML),
2、是采用注解的方式来实现(基于@AspectJ注解驱动的切面)。
具体使用方式
1.经典的基于代理的AOP实现,大致步骤为:配置文件中配置pointcut, 在java中用编写实际的aspect 类, 针对对切入点进行相关的业务处理。
JDK动态代理:动态代理是在运行时动态的生成一个代理类,在其中插入横切逻辑,在调用方法时不调用本来类的方法,转而调用代理类的方法
业务接口:
public interface IUserService { public String findUser(); }
public class UserServiceImpl implements IUserService{ private String name; public void setName(String name){ this.name=name; } public String getName(){ return this.name; } public String findUser(){ System.out.println("============执行业务方法findUser,查找的用户是:"+name+"============="); return name; } }
切面类:
public class AopAspect { public void doBefore(JoinPoint jp){ System.out.println("===========执行前置通知============"); } public void doAfterReturning(JoinPoint jp,String result){ System.out.println("===========执行后置通知============"); System.out.println("返回值result==================="+result); } public void doAfter(JoinPoint jp){ System.out.println("===========执行最终通知============"); } public void doAfterThrowing(JoinPoint jp,Exception ex){ System.out.println("===========执行异常通知============"); } public Object doAround(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("======执行环绕通知开始========="); Object result=pjp.proceed(); System.out.println("======执行环绕通知结束========="); return result; } }
Spring配置:
<!-- 声明一个业务类 --> <bean id="userManager" class="com.spring.service.impl.UserManagerServiceImpl"> <property name="name" value="lixiaoxi"></property> </bean> <!-- 声明通知类 --> <bean id="aspectBean" class="com.spring.aop.AopAspect" /> <aop:config> <aop:aspect ref="aspectBean"> <aop:pointcut id="pointcut" expression="execution(* com.spring.service.impl.UserManagerServiceImpl..*(..))"/> <aop:before method="doBefore" pointcut-ref="pointcut"/> <aop:after-returning method="doAfterReturning" pointcut-ref="pointcut" returning="result"/> <aop:after method="doAfter" pointcut-ref="pointcut" /> <aop:around method="doAround" pointcut-ref="pointcut"/> <aop:after-throwing method="doAfterThrowing" pointcut-ref="pointcut" throwing="ex"/> </aop:aspect> </aop:config>
二、使用注解配置AOP
采用注解来做aop, 主要是将写在spring 配置文件中的连接点写到注解里面。
业务接口和业务实现与上边一样,具体切面类如下:
@Aspect public class AopAspectJ { public static final String EDP="execution(* com.spring.service.impl.UserManagerServiceImpl..*(..))"; @Before(EDP) public void doBefore(JoinPoint jp){ System.out.println("=========执行前置通知=========="); } @AfterReturning(value=EDP,returning="result") public void doAfterReturning(JoinPoint jp,String result){ System.out.println("===========执行后置通知============"); } @After(value=EDP) public void doAfter(JoinPoint jp){ System.out.println("===========执行最终通知============"); } @Around(EDP) public Object doAround(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("======执行环绕通知开始========="); Object result=pjp.proceed(); System.out.println("======执行环绕通知结束========="); return result; } /** * 在目标方法非正常执行完成, 抛出异常的时候会走此方法 * @param jp * @param ex */ @AfterThrowing(value=EDP,throwing="ex") public void doAfterThrowing(JoinPoint jp,Exception ex) { System.out.println("===========执行异常通知============"); } }
spring的配置:
<!-- 声明spring对@AspectJ的支持 --> <aop:aspectj-autoproxy/> <!-- 声明一个业务类 --> <bean id="userManager" class="com.spring.service.impl.UserManagerServiceImpl"> <property name="name" value="lixiaoxi"></property> </bean> <!-- 声明通知类 --> <bean id="aspectBean" class="com.spring.aop.AopAspectJ" />