Spring-AOP(Aspect-orented programming)
在业务流程中插入与业务无关的逻辑,这样的逻辑称为Cross-cutting concerns,将Crossing-cutting concerns独立出来为一个对象,这样的特殊对象称为Aspect
Aspect,即方面。所谓方面,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。
方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的 Advisor或拦截器实现。
通知(Advice): 在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。Spring中定义了四个advice: BeforeAdvice, AfterAdvice, ThrowAdvice和DynamicIntroductionAdvice
切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点:例如,使用正则表达式。Spring定义了Pointcut接口,用来组合MethodMatcher和ClassFilter,可以通过名字很清楚的理解, MethodMatcher是用来检查目标类的方法是否可以被应用此通知,而ClassFilter是用来检查Pointcut是否应该应用到目标类上
实现方式:
1.使用Spring API实现
通知类型:前置通知、异常通知、后置通知、环绕通知、最终通知
后置通知:
1 public class LogAfter implements AfterReturningAdvice{ 2 /** 3 * 目标方法执行后执行的通知 4 * @param returnValue——返回值 5 * @param method 被调用方法对象 6 * @param args 被调用的方法的参数 7 * @param target 被调用的方法对象的目标对象 8 */ 9 @Override 10 public void afterReturning(Object returnValue, Method method, Object[] args, 11 Object target) throws Throwable { 12 System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行——后"); 13 } 14 }
前置通知:
1 public class LogBefore implements MethodBeforeAdvice{ 2 /** 3 * @param method 被调用方法对象 4 * @param args 被调用的方法的参数 5 * @param target 目标对象 6 */ 7 @Override 8 public void before(Method method, Object[] args, Object target) 9 throws Throwable { 10 System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行——前"); 11 } 12 }
1 <beans 2 xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xsi:schemaLocation= 6 "http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/aop 9 http://www.springframework.org/schema/aop/spring-aop.xsd"> 10 <!-- 声明一个切面 --> 11 <bean id="logBefore" class="com.zhengbin.log.LogBefore" /> 12 <bean id="logAfter" class="com.zhengbin.log.LogAfter" /> 13 14 <bean id="userService" class="com.zhengbin.service.UserServiceImpl"/> 15 <aop:config> 16 <!-- pointcut切入点 --> 17 <!-- execution(*[表示所有返回值] com.zhengbin.service[位置](..[表示所有参数])) --> 18 <aop:pointcut id="pointcut" expression="execution(* com.zhengbin.service.*.*(..))" /> 19 <!-- --> 20 <aop:advisor advice-ref="logAfter" pointcut-ref="pointcut"/> 21 <aop:advisor advice-ref="logBefore" pointcut-ref="pointcut"/> 22 </aop:config> 23 </beans>
2.自定义类实现
1 public class Log { 2 public void before(){ 3 System.out.println("执行前"); 4 } 5 public void after(){ 6 System.out.println("执行后"); 7 } 8 }
1 <beans 2 xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xsi:schemaLocation= 6 "http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/aop 9 http://www.springframework.org/schema/aop/spring-aop.xsd"> 10 <!-- 声明一个切面 --> 11 <bean id="log" class="com.zhengbin.log.Log"/> 12 <bean id="userService" class="com.zhengbin.service.UserServiceImpl"/> 13 <aop:config> 14 <aop:aspect ref="log"> 15 <aop:pointcut expression="execution(* com.zhengbin.service.*.*(..))" id="pointCut"/> 16 <aop:before method="before" pointcut-ref="pointCut"/> 17 <aop:after method="after" pointcut-ref="pointCut"/> 18 </aop:aspect> 19 </aop:config> 20 </beans>
3.通过注解实现
启用Spring对@AspectJ的支持:
<aop:aspectj-autoproxy/>
1 @Aspect 2 public class Log { 3 @Before("execution(* com.zhengbin.service.*.*(..))") 4 public void before(){ 5 System.out.println("执行前"); 6 } 7 @After("execution(* com.zhengbin.service.*.*(..))") 8 public void after(){ 9 System.out.println("执行后"); 10 } 11 }
1 <beans 2 xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xsi:schemaLocation= 6 "http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/aop 9 http://www.springframework.org/schema/aop/spring-aop.xsd"> 10 <!-- 声明一个切面 --> 11 <bean id="log" class="com.zhengbin.log.Log"/> 12 13 <bean id="userService" class="com.zhengbin.service.UserServiceImpl"/> 14 15 <!-- 启用Spring对@AspectJ的支持 --> 16 <aop:aspectj-autoproxy/> 17 </beans>