service层AOP(基于注解的方法切入)
一、导入Maven依赖包
<dependency>< groupId >org.aspectj groupId >
<artifactId>aspectjweaverartifactId>
<version>1.8.9version>
dependency>
<dependency>
<groupId>cglibgroupId>
<artifactId>cglibartifactId>
<version>2.2.2version>
dependency>
<aop:aspectj-autoproxy/> <aop:aspectj-autoproxy proxy-target-class="true" />
三、编写注解类 @interface ServiceAopAnn
import java.lang.annotation.*; @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ServiceAopAnno { String value() default ""; boolean required() default true; }
四、编写AOP切面处理类 ServiceAspect import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component;
import org.slf4j.Logger; import org.slf4j.LoggerFactory;@Aspect @Component public class ServiceAspect {
protected Logger logger = LoggerFactory.getLogger(this.getClass()); //Service层切点 @Pointcut("@annotation(ServiceAopAnno)") public void serviceAspect() { } @Around("serviceAspect()") public void doAround(ProceedingJoinPoint joinPoint) throws Throwable { Object target = joinPoint.getTarget(); Object[] args = joinPoint.getArgs(); if(logger.isDebugEnabled()){ logger.debug("doAround_begin: target: {} ,args: {}" ,target ,args); }
//TODO do something before proceed
//do target.method try { Object obj = joinPoint.proceed(); } catch (Throwable e) { logger.error("doAround_proceed error:" + e.getMessage() , e); throw e; }
//TODO do something after proceed
if(logger.isDebugEnabled()){ logger.debug("doAround_end: target: {} ,args: {}" ,target ,args); } } }
五、service实现类添加AOP切面注解
@Service("messageService") public class MessageServiceImpl implements MessageService {}
六、注意事项
1. 确认你的bean 是AopProxy代理的对象:
AopUtils.isAopProxy()//
AopUtils.isCglibProxy() //cglib
AopUtils.isJdkDynamicProxy() //jdk动态代理
2. context:component-scan 重复扫描(bean实例化多次)可能影响事务;
3. 基于类的代理而非接口,如果想代理父类的方法,可以用 execution(* com.sishuok.es..service..*+.*(..))4. 切面只能添加到public方法上。