注解之使用注解来实现切点和advice(3)

前面的注解之注解可以看到注解是标记,既然是标记那么就可以用来区分信息的

区分信息之后我们的动作更加丰富,我们可以使用注解来标记类,这些类就是我们的切点切出来的面上的元素.


本节内容呢我们使用注解来完成切点功能,然后使用aop计算凡是被标记的方法的执行时间


准备知识

aop基本知识回顾

1.aop的知识  ,切点,advice ,切点和advice的绑定即  advisor
   这部分知识大家都不会陌生的
   之前我们做项目总在xml中进行配置的
    典型的写法
     
<aop:config>									
	<aop:pointcut id="txPointcut"	expression="execution(* com.xxx.service.impl.*ServiceImpl.*(..))" />								
	<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />								
</aop:config>	

这是一个典型的配置方式,我们定义的切点使用了execution表达式完成

然后再定义一个advice ,这里我们仍然以典型的事务管理的advice来看

<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<!-- 所有可写的方法都加入事务管理 -->
			<tx:method name="save*" propagation="REQUIRED"/>
			<tx:method name="update*" propagation="REQUIRED"/>
			<tx:method name="delete*" propagation="REQUIRED"/>
			<tx:method name="add*" propagation="REQUIRED"/>
			<tx:method name="remove*" propagation="REQUIRED"/>
			<tx:method name="sync*" propagation="REQUIRED"/>
			<tx:method name="execute*" propagation="REQUIRED"/>

			<!-- 其它方法为只读事务 -->
			<tx:method name="*" read-only="true" />

			<!--   
				事务传播行为类型  
				REQUIRED  如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。  
				SUPPORTS   支持当前事务,如果当前没有事务,就以非事务方式执行。  
				MANDATORY  使用当前的事务,如果当前没有事务,就抛出异常。  
				REQUIRES_NEW  新建事务,如果当前存在事务,把当前事务挂起。  
				NOT_SUPPORTED   以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。  
				NEVER   以非事务方式执行,如果当前存在事务,则抛出异常。  
				NESTED  如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。  
			-->  
		</tx:attributes>
	</tx:advice>


2.后端java涉及的类

 JoinPoint , ProceedingJoinPoint , MethodInterceptor , MethodInvocation , RunTimeAnno  , MethodSignature

@Around , @Pointcut @Aspect ...



下面我们看如何使用注解来完成一个计算  方法的执行时间的aop配置


一 定义一个注解的类用于标记 TimeSpend

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface TimeSpend {

    String value() default "";

}



二 配置AOP ,定义为 TimeSpendAspect

@Aspect
@Component
public class TimeSpendAspect {

    @Pointcut("execution(* cn.XXXX..*.*(..))")
    public void pointcut() {

    }

    @Around(value = "@annotation(cn.creditease.zma.trade.common.annotation.TimeSpend)")
    public Object timeSpend(ProceedingJoinPoint jp) throws Throwable {
        Logger logger = LoggerFactory.getLogger(this.getClass(jp));
        Long begin = new Date().getTime();
        String className = this.getClassName(jp);
        String methodName = this.getMethodName(jp);
        String output = "----------调用【" + className + "】类的【" + methodName + "】方法,";
        String annoValue = getAnnoValue(jp);
        if (annoValue != null) {
            output = "----------" + annoValue + ",";
        }
        Object result = jp.proceed();
        Long end = new Date().getTime();
        Long spendTime = (end - begin) / Constants.MILLON_INT;
        logger.info(output + "耗时:" + spendTime + "s----------");
        return result;
    }

    public Class getClass(JoinPoint jp) {
        return jp.getTarget().getClass();
    }

    public String getClassName(JoinPoint jp) {
        return jp.getTarget().getClass().getName();
    }

    public String getMethodName(JoinPoint jp) {
        return jp.getSignature().getName();
    }

    public String getAnnoValue(ProceedingJoinPoint jp) {
        Signature signature = jp.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method targetMethod = methodSignature.getMethod();
        if (targetMethod.isAnnotationPresent(TimeSpend.class)) {
            TimeSpend timeSpend = (TimeSpend) targetMethod.getAnnotation(TimeSpend.class);
            return timeSpend.value();
        }
        return null;
    }
}


三 使用注解来标记方法

    @TimeSpend("流水入库以及自动匹配")
    @Override
    public void doStorageAndMatch() {
        // 1.流水入库
        try {
            arrivalFlowStorageBatch.arrivalFlowStorageJob();
        } catch (Exception e) {
            LOGGER.error("流水入库异常",e);
        }
        // 2.自动匹配
        flowAutoMatchBatchAbstract.autoMatch();
    }


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值