Spring Aop 基于XML的配置 && 注解配置 (有源码)

 

这篇文章主要是对AOP的例子,如果大家对Spring Aop的知识感兴趣,可以阅读博主这篇 SpringAop 理解(一) 文章,我把xml配置和注解配置分成2个项目,已经上传github,大家可以文章末尾进行下载源码。

 

基于注解配置

1、新增切面类(重点 实际比如记录日志可以在切面类中进行写操作,这样业务代码中不会有太多与业务无关的代码

@Aspect
@Component
public class LogAspect {
	
    @Pointcut("@annotation(com.aop.annotation.Action)")
    public void annotationPointCut() {
        System.out.println("annotationPointCut");
    }
    
    /**
     * 
     * 后置通知:
     * 	      在目标方法完成之后调用通知,此时不会关心方法的输出是什么
     *     (此方法使用自定义注解进行配置)
     */
    @After("annotationPointCut()")
    public void after(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method method = signature.getMethod();
        Action action = method.getAnnotation(Action.class);
        System.out.println("后置通知 —— 方法名称:" + action.name());
    }
    
    /**
     * 返回通知:
     * 	     在目标方法成功执行之后调用通知,调用此拦截会返回方法所返回的值。
     */
     @AfterReturning(value="execution(* com.aop.service.DemoMethodService.*(..))", returning="result")
     public void afterReturning(Object result){
             System.out.println("返回通知 —— 方法名称:"+result);
     }
     /**
      * 异常通知:
      * 	在目标方法抛出异常后调用通知
      */
     @AfterThrowing(value="execution(* com.aop.service.DemoMethodService.*(..))" , throwing="e")
     public void find(Throwable e ){
             System.out.println("异常抛出通知======"+e.getMessage());
     }
     
    /**
     * 前置通知:
     * 	      在目标方法被调用之前调用通知功能
     */
    @Before("execution(* com.aop.service.DemoMethodService.*(..))")
    public void before(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("前置通知 —— 方法名称:" + method.getName());
    }
    
    /**
     * 环绕通知
     * 	     在被通知的方法调用之前和调用之后执行自定义的行为
     */
    @Around(value="execution(* com.aop.service.DemoMethodService.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕前通知=========start=============");
        Object obj=joinPoint.proceed();//执行目标方法
        System.out.println("环绕后通知==========end============");
        return obj;
    }
    
}

2、增加AopConfig 配置类,增加这个类是为了扫描注解。

@Configuration
@ComponentScan("com.aop")
@EnableAspectJAutoProxy
public class AopConfig {

}

3、新增一个自定义注解(使用自定义注解,配置到方法中这样代码更加简便)

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented

public @interface Action {
    String name();
}

4、新增Demo使用自定义注解

@Service
public class DemoAnnotationService {
	
    @Action(name = "注解式拦截的add操作")
    public void add() {
        System.out.println("执行到DemoAnnotationService的add方法");
        System.out.println("DemoAnnotationService.add方法结束");
    }
}

5、不使用自定注解

@Service
public class DemoMethodService {
	
    public void add() {
        System.out.println("DemoMethodService.add()");
    }
    
}

6、测试方法

public class App 
{
    public static void main( String[] args )
    {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);
        // 获取自定义注解类
        DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class);
        // 获取普通方法类
        DemoMethodService demoMethodService = context.getBean(DemoMethodService.class);
        //基于注解的拦截
        demoAnnotationService.add();
        //给予方法规则的拦截
        demoMethodService.add();
        context.close();
    }
}

7、测试结果

执行到DemoAnnotationService的add方法
DemoAnnotationService.add方法结束
后置通知 —— 方法名称:注解式拦截的add操作
环绕前通知=========start=============
前置通知 —— 方法名称:add
DemoMethodService.add()
环绕后通知==========end============
返回通知 —— 方法名称:null

基于XML文件配置

使用的是上面的例子,把注解去掉,使用配置文件。

下面是 application.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    <!-- 配置切面的bean -->
    <bean id="logaspect" class="com.aop.aspect.LogAspect"></bean>   
    <bean id="methodService" class="com.aop.service.DemoMethodService"></bean>   
    

    <!-- 配置AOP -->
    <aop:config>
        <!-- 配置切面表达式 -->
        <aop:pointcut expression="execution(* com.aop.service.DemoMethodService.*(..))"
         id="pointcut"/>
        <!-- 配置切面和通知 
             order:优先级,越小优先级越高-->
        <aop:aspect ref="logaspect" order="1">
            <aop:before method="before" pointcut-ref="pointcut"/>
        </aop:aspect>
        <aop:aspect ref="logaspect" order="2">
            <aop:before method="after" pointcut-ref="pointcut"/>
        </aop:aspect>
    </aop:config>
</beans>

总结

大家是不是发现例子比较简单,有的时候是我们把困难想的太复杂了,勇于实践,勇于做自己觉得复杂的事情,相信你们是最棒的!

GitHub :https://github.com/xiaonongOne/spring-aop-parent

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值