「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。
前言
基于上篇介绍玩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" />
\