AOP(Aspect Oriented Programming):
被称为面向切面编程,是OOP(面向对象编程的一种补充),主要用来解决一些系统层面上的问题
AOP的三种实现方式:
1.基于Spring容器的自动代理实现AOP:
<!--被代理对象-->
<bean id="orderServiceTargetBean" class="com.apesource.service.impl.OrderServiceImpl"/>
<bean id="userServiceTargetBean" class="com.apesource.service.impl.UserServiceImpl"/>
<!--通知(Advice)-->
<bean id="logAdviceBean" class="com.apesource.LogAdvice"/>
<bean id="performanceAdviceBean" class="com.apesource.PerformanceAdvice"/>
<!--切入点(Poinecut)-->
<bean id="createPointcutBean" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*create.*"/>
</bean>
<!--Advisor(高级通知) = Advice(通知) + Pointcut(切入点)-->
<bean id="performanceAdvisorBean" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<!--注入通知-->
<property name="advice" ref="performanceAdviceBean"/>
<!--注入切入点-->
<property name="pointcut" ref="createPointcutBean"/>
</bean>
<!--自动代理对象-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!--被代理对象(目标对象)列表:根据Bean名称规则指定那些bean创建自动代理-->
<property name="beanNames">
<list>
<value>*TargetBean</value>
</list>
</property>
<!--通知列表-->
<property name="interceptorNames">
<list>
<value>logAdviceBean</value>
<value>performanceAdvisorBean</value>
</list>
</property>
</bean>
2.AspectJ技术,通过切面Aspect,基于Spring AOP的配置实现AOP:
@Before(EXPRESSION)
public void beforeAdvice(JoinPoint joinPoint){
System.out.println("=========【使用AspectJ实现前置通知】开始=========");
System.out.println("目标对象:" + joinPoint.getTarget());
System.out.println("目标方法:" + joinPoint.getSignature().getName());
System.out.println("参数列表:" + joinPoint.getArgs());
System.out.println("=========【使用AspectJ实现前置通知】结束=========");
}
public Object afterReturningAdvice(JoinPoint joinPoint, Object returnValue){
System.out.println("=========【使用AspectJ实现后置通知】开始=========");
System.out.println("目标对象:" + joinPoint.getTarget());
System.out.println("目标方法:" + joinPoint.getSignature().getName());
System.out.println("参数列表:" + joinPoint.getArgs());
System.out.println("返回值:" + returnValue);
System.out.println("=========【使用AspectJ实现后置通知】结束=========");
return returnValue;
}
public void afterAdvice(JoinPoint joinPoint){
System.out.println("=========【使用AspectJ实现后置通知】开始=========");
System.out.println("目标对象:" + joinPoint.getTarget());
System.out.println("目标方法:" + joinPoint.getSignature().getName());
System.out.println("参数列表:" + joinPoint.getArgs());
System.out.println("=========【使用AspectJ实现后置通知】结束=========");
}
public void throwingAdvice(JoinPoint joinPoint, Exception ex){
System.out.println("=========【使用AspectJ实现异常通知】开始=========");
System.out.println("目标对象:" + joinPoint.getTarget());
System.out.println("目标方法:" + joinPoint.getSignature().getName());
System.out.println("出现异常:" + ex.getMessage());
System.out.println("=========【使用AspectJ实现异常通知】结束=========");
}
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("=========######【使用AspectJ实现环绕通知】######开始=========");
Object returnValue = joinPoint.proceed();
System.out.println("=========######【使用AspectJ实现环绕通知】######结束=========");
return returnValue;
}
<!--被代理对象(目标对象)bean-->
<bean id="orderServiceBean" class="com.apesource.service.impl.OrderServiceImpl"/>
<bean id="userServiceBean" class="com.apesource.service.impl.UserServiceImpl"/>
<!--日志Aspect切面bean-->
<bean id="logAspectBean" class="com.apesource.aspect.LogAspect"/>
<!--使用Aspect实现切面,使用Spring AOP进行配置-->
<aop:config>
<!--配置切面-->
<!--注入切面bean-->
<aop:aspect ref="logAspectBean">
<!--定义Pointcut:通过expression表达式,来查找特定的方法(pointcut)-->
<aop:pointcut id="serviceMethodPointuct" expression="execution(* com.apesource.service.impl.*.create*(..) )"/>
<!--配置“前置通知”-->
<!--在pointcut切入点(serviceMethodPointuct)查找到的方法执行“前”,执行当前logAspectBean的beforeAdvice前置通知方法-->
<aop:before method="beforeAdvice" pointcut-ref="serviceMethodPointuct"/>
<!--配置“后置通知”(有返回值)-->
<!--在pointcut切入点(serviceMethodPointuct)查找到的方法执行“后”,执行当前logAspectBean的afterReturningAdvice后置通知方法-->
<aop:after-returning returning="returnValue" method="afterReturningAdvice" pointcut-ref="serviceMethodPointuct"/>
<!--配置“后置通知”(无返回值)-->
<!--在pointcut切入点(serviceMethodPointuct)查找到的方法执行“后”,执行当前logAspectBean的afterAdvice后置通知方法-->
<aop:after method="afterAdvice" pointcut-ref="serviceMethodPointuct"/>
<!--配置“异常通知”-->
<!--在pointcut切入点(serviceMethodPointuct)查找到的方法执行中出现异常时,执行当前logAspectBean的throwingAdvice异常通知方法-->
<aop:after-throwing throwing="ex" method="throwingAdvice" pointcut-ref="serviceMethodPointuct"/>
<!--配置“异常通知”(有返回值)-->
<!--在pointcut切入点(serviceMethodPointuct)查找到的方法执行前后,执行当前logAspectBean的aroundAdvice环绕通知方法(包括前置和后置)-->
<aop:around method="aroundAdvice" pointcut-ref="serviceMethodPointuct"/>
</aop:aspect>
</aop:config>
</beans>
3.通过注解实现AOP:
<!--自动扫描器-->
<context:component-scan base-package="com.apesource"/>
<!--配置AspectJ的动态代理-->
<aop:aspectj-autoproxy/>
</beans>
@Before(EXPRESSION)
public void beforeAdvice(JoinPoint joinPoint){
System.out.println("=========【使用AspectJ实现前置通知】开始=========");
System.out.println("目标对象:" + joinPoint.getTarget());
System.out.println("目标方法:" + joinPoint.getSignature().getName());
System.out.println("参数列表:" + joinPoint.getArgs());
System.out.println("=========【使用AspectJ实现前置通知】结束=========");
}
@AfterReturning(value = EXPRESSION,returning = "returnValue")
public Object afterReturningAdvice(JoinPoint joinPoint, Object returnValue){
System.out.println("=========【使用AspectJ实现后置通知】开始=========");
System.out.println("目标对象:" + joinPoint.getTarget());
System.out.println("目标方法:" + joinPoint.getSignature().getName());
System.out.println("参数列表:" + joinPoint.getArgs());
System.out.println("返回值:" + returnValue);
System.out.println("=========【使用AspectJ实现后置通知】结束=========");
return returnValue;
}
@After(EXPRESSION)
public void afterAdvice(JoinPoint joinPoint){
System.out.println("=========【使用AspectJ实现后置通知】开始=========");
System.out.println("目标对象:" + joinPoint.getTarget());
System.out.println("目标方法:" + joinPoint.getSignature().getName());
System.out.println("参数列表:" + joinPoint.getArgs());
System.out.println("=========【使用AspectJ实现后置通知】结束=========");
}
@AfterThrowing(value = EXPRESSION,throwing = "ex")
public void throwingAdvice(JoinPoint joinPoint, Exception ex){
System.out.println("=========【使用AspectJ实现异常通知】开始=========");
System.out.println("目标对象:" + joinPoint.getTarget());
System.out.println("目标方法:" + joinPoint.getSignature().getName());
System.out.println("出现异常:" + ex.getMessage());
System.out.println("=========【使用AspectJ实现异常通知】结束=========");
}
@Around(EXPRESSION)
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("=========######【使用AspectJ实现环绕通知】######开始=========");
Object returnValue = joinPoint.proceed();
System.out.println("=========######【使用AspectJ实现环绕通知】######结束=========");
return returnValue;
}