• Spring boot之AOP面向切面编程


    转载自:https://blog.csdn.net/yangshangwei/article/details/77619875

    @annotation()概述

    @annotation表示标注了某个注解的所有方法。

    下面通过一个实例说明@annotation()的用法。 AnnotationTestAspect定义了一个后置切面增强,该增强将应用到标注了NeedTest的目标方法中。


    实例

    代码已托管到Github—> https://github.com/yangshangwei/SpringMaster

    首先我们先自定义一个注解@NeedTest。

    如何自定义注解请参考Java-Java5.0注解解读

    package com.xgj.aop.spring.advisor.aspectJ.function;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 
     * 
     * @ClassName: NeedTest
     * 
     * @Description: 自定义注解@NeedTest
     * 
     * @author: Mr.Yang
     * 
     * @date: 2017年8月26日 下午11:19:12
     */
    
    // 声明注解的保留期限
    @Retention(RetentionPolicy.RUNTIME)
    // 声明可以使用该注解的目标类型
    @Target(ElementType.METHOD)
    @Documented
    public @interface NeedTest {
    	// 声明注解成员 一个数值,在注解使用的时候,括号里面赋值
    	boolean value() default false;
    }
    

      下面我们定义接口 Waiter

    package com.xgj.aop.spring.advisor.aspectJ.function;
    
    public interface Waiter {
    	public void greetTo(String clientName);
    
    	public void serverTo(String clientName);
    }
    

      接口实现类 两个NaiveWaiter 和 NaughtWaiter

    package com.xgj.aop.spring.advisor.aspectJ.function;
    
    public class NaiveWaiter implements Waiter {
    
    	@NeedTest(true)
    	@Override // 重写,编译器帮忙验证@Override下面的方法名是否是你父类中所有的,如果没有则报错
    	public void greetTo(String clientName) {
    		System.out.println("NaiveWaiter:greet to " + clientName);
    	}
    
    	@Override
    	public void serverTo(String clientName) {
    		System.out.println("NaiveWaiter:server to " + clientName);
    	}
    
    	public void smile(String clientName, int times) {
    		System.out.println("NaiveWaiter:smile to  " + clientName + " " + times
    				+ " times");
    	}
    }
    

      

    package com.xgj.aop.spring.advisor.aspectJ.function;
    
    public class NaughtWaiter implements Waiter {
    
    	@Override
    	public void greetTo(String clientName) {
    		System.out.println("NaughtWaiter:greet to " + clientName);
    	}
    
    	@NeedTest(true)
    	@Override
    	public void serverTo(String clientName) {
    		System.out.println("NaughtWaiter:server to " + clientName);
    	}
    
    	public void joke(String clientName, int times) {
    		System.out.println("NaughtyWaiter:play " + times + " jokes to "
    				+ clientName);
    	}
    }
    

      我们可以看到 NaiveWaiter#greetTo()方法使用了@NeedTest注解, NaughtWaiter#serverTo()也使用了@NeedTest注解,我们的目标就是将后置增强织入到这两个标注了@NeedTest的方法中。


    接下来编写切面的横切逻辑

    package com.xgj.aop.spring.advisor.aspectJ.function.annotationFun;
    
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Aspect;
    
    /**
     * 
     * 
     * @ClassName: AnnotationTestAspect
     * 
     * @Description: 切面 、 后置增强 ,@annotation表示标注了某个注解的所有方法
     * 
     * @author: Mr.Yang
     * 
     * @date: 2017年8月26日 下午11:23:53
     */
    
    @Aspect
    public class AnnotationTestAspect {
        // @annotation 用于匹配当前执行方法持有指定注解的方法
    	@AfterReturning("@annotation(com.xgj.aop.spring.advisor.aspectJ.function.NeedTest)")
    	public void needTest() {
    		System.out.println("needTest() executed,some logic is here");
    	}
    
    }
    

      接下来通过Spring自动应用切面,配置文件如下

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	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.xsd">
    
    <!-- 使用基于Schema的aop命名空间进行配置 -->
     
    
    <!-- 基于@AspectJ切面的驱动器 -->
    <aop:aspectj-autoproxy/>
     
    <!-- 目标Bean -->
    <bean id="naiveWaiter" class="com.xgj.aop.spring.advisor.aspectJ.function.NaiveWaiter"/>
    
    <bean id="naughtWaiter" class="com.xgj.aop.spring.advisor.aspectJ.function.NaughtWaiter"/>
    
    <!-- 使用了@AspectJ注解的切面类 -->
    <bean class="com.xgj.aop.spring.advisor.aspectJ.function.annotationFun.AnnotationTestAspect"/>
    
    </beans>
    

      最后编写测试代码:

    package com.xgj.aop.spring.advisor.aspectJ.function.annotationFun;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.xgj.aop.spring.advisor.aspectJ.function.Waiter;
    
    public class AnnotationTestAspcetTest {
    
    	@Test
    	public void test() {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext(
    				"com/xgj/aop/spring/advisor/aspectJ/function/annotationFun/conf-annotation.xml");
    
    		// 必须是接口类型,否则抛类型转换异常
    		Waiter waiter = (Waiter) ctx.getBean("naiveWaiter");
    
    		// 因为greetTo标注了@NeedTest,因此会被后置增强
    		waiter.greetTo("XiaoGongJiang");
    		waiter.serverTo("XiaoGongJiang");
    
    		Waiter naughtWaiter = (Waiter) ctx.getBean("naughtWaiter");
    		// serverTo标注了@NeedTest,因此会被后置增强
    		naughtWaiter.serverTo("XiaoGongJiang");
    	}
    }
    

      运行结果:

    2017-08-27 01:24:22,551  INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6ac604: startup date [Sun Aug 27 01:24:22 BOT 2017]; root of context hierarchy
    2017-08-27 01:24:22,647  INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/aspectJ/function/annotationFun/conf-annotation.xml]
    NaiveWaiter:greet to XiaoGongJiang
    needTest() executed,some logic is here
    NaiveWaiter:server to XiaoGongJiang
    NaughtWaiter:server to XiaoGongJiang
    needTest() executed,some logic is here
    

      

  • 相关阅读:
    Android拍照+方形剪裁——附代码与效果图
    Caffe源代码中Solver文件分析
    Java学习笔记五(多线程)
    setTimeout和setInterval的区别
    javascript中this的妙用
    javascript基于原型的语言的特点
    css样式小技巧
    html块元素和内联元素
    怎么解决浏览器兼容性问题
    高效率、简洁、CSS代码优化原则
  • 原文地址:https://www.cnblogs.com/lzh1043060917/p/13815699.html
Copyright © 2020-2023  润新知