1.2、AOP
AOP(Aspect Oriented Programming):面向切面编程,在不改变原程序的基础上增加新的功能。
使用场景:做日志切面,权限切面。
AOP的增强方式有5种:
- befor:前置增强,在执行目标方法前触发
- after:最终增强,不管异常是否发生都一定会触发
- afterReturn:后置增强,如果发生异常不会被执行
- afterThrowing:异常增强,如果发生指定类型时触发
- around:环绕增强,前置增强和后置增强的综合体。
1.2.1、配置版
execution(* com.loongshawn.method.ces…* .*(…))
标识符 | 含义 |
---|---|
execution() | 表达式的主体 |
第一个“*”符号 | 表示返回值的类型任意 |
com.loongshawn.method.ces | AOP所切的服务的包名,即,需要进行横切的业务类 |
包名后面的“…” | 表示当前包及子包 |
第二个“*” | 表示类名,*即所有类 |
.*(…) | 表示任何方法名,括号表示参数,两个点表示任何参数类型 |
<!-- 配置aop -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut expression="execution(public * com.aop.conf.service.*.*(..))" id="pointcut"/>
<!-- 配置切面 -->
<!-- ref:配置执行切面的业务处理类 -->
<aop:aspect ref="serviceLogging">
<!-- 配置前置增强
<aop:before method="before" pointcut-ref="pointcut" />-->
<!-- 后置增强:如果发生异常不会执行 -->
<!-- returning:方法的参数名必须一致 -->
<aop:after-returning method="afterReturning" returning="returnVal" pointcut-ref="pointcut" />
<!-- 最终增强:不管是否发生异常都一定会执行 -->
<aop:after method="after" pointcut-ref="pointcut"/>
<!-- 异常增强 -->
<!-- throwing:值要与方法的参数名一致 -->
<aop:after-throwing method="afterThrowing" throwing="ex" pointcut-ref="pointcut"/>
<!-- 环绕增强 -->
<aop:around method="around" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
1.2.2、注解版
-
日志业务类
package com.aop.annotation.log; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect //面向切面 @Component //要加上类的bean的组件配置 public class ServiceLogging { private Log log = LogFactory.getLog(this.getClass()); @Pointcut("execution(public * com.aop.annotation.service.*.*(..))") public void myPointcut(){} // @Before("execution(public * com.aop.annotation.service.*.*(..))") @Before("myPointcut()") public void before(JoinPoint joinPoint){ log.info("前置增强处理被执行"); log.info("连接点对象:"+joinPoint.getTarget().getClass().getSimpleName()); log.info("连接点方法:"+joinPoint.getSignature()); log.info("连接点方法参数:"+joinPoint.getArgs()[0]); log.info("------------------"); log.debug("debug..."); log.info("info..."); log.warn("warn..."); log.error("error..."); log.fatal("fatal..."); } // @After("execution(public * com.aop.annotation.service.*.*(..))") @After("myPointcut()") public void after(){ log.info("最终增强处理被执行"); } @AfterReturning(pointcut="myPointcut()",returning="returnVal") public void afterReturning(Object returnVal){ log.info("后置增强处理被执行"); log.info("后置增强处理:方法返回值为:"+returnVal); } @AfterThrowing(pointcut="myPointcut()",throwing="ex") public void afterThrowing(Exception ex){ log.info("业务方法抛出了异常,异常增强处理被执行"); log.info("抛出的异常为:"+ex.getMessage()); } @Around("myPointcut()") public Boolean around(ProceedingJoinPoint pjp) throws Throwable{ log.info("环绕增强处理:目标方法执行前织入"); log.info("环绕增强处理:目标方法的参数:"+pjp.getArgs()[0]); Boolean b = null; if(true){ b = (Boolean)pjp.proceed(pjp.getArgs()); } log.info("环绕增强处理:目标方法的返回值为:"+b); log.info("环绕增强处理:目标方法执行后织入"); return b; } }
-
执行切入点的业务类
package com.aop.annotation.service.impl; import org.springframework.stereotype.Service; import com.aop.annotation.entity.User; import com.aop.annotation.service.UserService; @Service public class UserServiceImpl implements UserService { @Override public boolean addUser(User entity) { System.out.println("add User..."); // int i=1/0; return false; } }
-
测试类
package com.aop.annotation.test; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.aop.annotation.entity.User; import com.aop.annotation.service.UserService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:applicationContext-annotation.xml") public class TestUser { @Autowired //byType private UserService userService1; @Test public void test1(){ userService1.addUser(new User()); } }