zoukankan      html  css  js  c++  java
  • 基于注解的Spring AOP示例

    基于注解的Spring AOP示例

    在XML配置文件中开启 @AspectJ 支持

    要使用Spring的AOP,首先要在 applicationContext.xml 配置文件中添加如下内容:

    <!-- 启动@Aspectj -->
    <aop:aspectj-autoproxy/>
    

    声明切面及切入点

    在Spring中, 切面 就是使用 @Aspect 注解的类。而 切入点 则由两部分组成:方法签名和切入点表达式。下面的切面中声明了三种切入点。

    @Aspect
    public class SampleAspect {
        // 匹配所有的公共方法
        @Pointcut("execution(public * *(..))")
        public void publicMethod() {
        }
    
        // 匹配所有在com.app.bean包中的方法
        @Pointcut("within(com.app.bean.*)")
        public void inPackage() {
        }
    
        // 匹配所有带有CustomAnnotation注解的方法
        @Pointcut("@annotation(com.app.annotation.CustomAnnotation)")
        public void withAnnotation() {
        }
    }
    

    其中第三个切入点使用了自定义的注解类 CustomAnnotation

    public @interface CustomAnnotation {}
    

    声明通知

    接下来要声明的是 通知 ,通知与切面的结构基本一致。不同的是通知使用 @Before@Around 等注解同切面中的切入点一起确定执行的方法。下面的通知示例中声明了三种通知方式,其中 @Around 类型的通知需要一个 ProceedingJoinPoint 类的实例作为参数。

    @Aspect
    public class SampleAdvice {
        @Before("com.app.aspect.SampleAspect.publicMethod()")
        public void advicePublicMethod() {
            System.out.println("before advice matched with public methods");
        }
    
        @After("com.app.aspect.SampleAspect.inPackage()")
        public void adviceInBean() {
            System.out.println("after advice matched methods in package");
        }
    
        @Around("com.app.aspect.SampleAspect.withAnnotation()")
        public Object adviceWithAnnotation(ProceedingJoinPoint jp) throws Throwable {
            System.out.println("around advice before proceed");
            Object ret = jp.proceed();
            System.out.print("around advice after proceed");
            return ret;
        }
    }
    

    之前声明的切面和通知都需要在配置文件中声明一下,最终的 applicationContext.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:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
                               http://www.springframework.org/schema/beans/spring-beans.xsd
                               http://www.springframework.org/schema/context
                               http://www.springframework.org/schema/context/spring-context.xsd
                               http://www.springframework.org/schema/aop
                               http://www.springframework.org/schema/aop/spring-aop.xsd">
      <context:component-scan base-package="com.app"/>
      <!-- 启动@Aspectj -->
      <aop:aspectj-autoproxy/>
    
      <!-- 切面 -->
      <bean id="sampleAspect" class="com.app.aspect.SampleAspect"/>
      <!-- 通知 -->
      <bean id="sampleAdvice" class="com.app.aspect.SampleAdvice"/>
    </beans>
    

    测试

    现在可以写一个普通的类来测试我们的代码了,在 com.app.bean 包中创建文件:

    @Component
    public class CommonService {
        public void service() {
            System.out.println("service method");
        }
    
        public void transfer() {
            System.out.println("transfer method");
        }
    
        @CustomAnnotation
        public void annotated() {
            System.out.println("method with annotation");
        }
    }
    

    测试代码如下:

    public class Test {
        public static void main(String[] args){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            CommonService service = context.getBean("commonService", CommonService.class);
            service.service();
            service.transfer();
            service.annotated();
        }
    }
    

    结语

    本文中的示例代码是基于Maven项目的,最终代码的包结构如下:

    pom.xml 文件内容:

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.eagle</groupId>
      <artifactId>springDemo</artifactId>
      <version>1.0-SNAPSHOT</version>
    
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.0.4.RELEASE</version>
        </dependency>
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
          <version>1.8.2</version>
        </dependency>
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjrt</artifactId>
          <version>1.8.2</version>
        </dependency>
        <dependency>
          <groupId>log4j</groupId>
          <artifactId>log4j</artifactId>
          <version>1.2.17</version>
        </dependency>
      </dependencies>
    </project>
    
  • 相关阅读:
    数据库中的 索引
    JQuery中ajax请求
    如何优化广告,提高点击率
    常用的正则表达式
    全栈工程师之路中级篇之小程序开发前言
    ionic入门教程第四课使用$controllerProvider按需加载controller
    全栈工程师之路中级篇之小程序开发第一章第一节注册小程序
    ionic入门教程第三课在项目中使用requirejs分离controller文件和server文件
    ionic入门教程第五课举例子说明异步回调$q及$q在项目中的用法
    求两个整数的最大公约数和最小公倍数
  • 原文地址:https://www.cnblogs.com/sungoshawk/p/3948231.html
Copyright © 2011-2022 走看看