设为首页 加入收藏

TOP

Spring AOP官方文档学习笔记(二)之基于注解的Spring AOP(一)
2023-07-25 21:31:41 】 浏览:63
Tags:Spring AOP 方文档 习笔记 于注解

1.@Aspect注解

(1) @Aspect注解用于声明一个切面类,我们可在该类中来自定义切面,早在Spring之前,AspectJ框架中就已经存在了这么一个注解,而Spring为了提供统一的注解风格,因此采用了和AspectJ框架相同的注解方式,这便是@Aspect注解的由来,换句话说,在Spring想做AOP框架之前,AspectJ AOP框架就已经很火了,而直接把AspectJ搬过来又不现实,因此,Spring想了一个折中的方案,即只使用AspectJ框架的声明,写法和定义方式(比如@Aspect注解),而底层由Spring自己实现,这样,就避免了我们程序员从AspectJ AOP切换到Spring AOP后,还要再去学一套新的写法了,也正因为如此,如果想要使用Spring AOP,就必须依赖aspectjweaver.jar包(不然谁来提供写法和定义方式),我们可以通过maven进行导入,如下

<!-- 添加对AspectJ框架的依赖 -->
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.9.5</version>
</dependency>

<!-- 除了上面的方式外,也可以直接使用spring-aspects依赖,它里面包含了对AspectJ的依赖 -->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>${spring.framework.version}</version>
</dependency>

(2) 同时还需使用@EnableAspectJAutoProxy注解来开启Spring对于AspectJ注解的支持,如下

@Configuration
@EnableAspectJAutoProxy
public class Config {

}

如果是基于xml的配置,可通过如下标签进行开启

<aop:aspectj-autoproxy/>

2.自定义一个切面类

(1) 在基于注解的配置下,除了使用@Aspect注解外,还需要声明该切面是一个bean,否则,spring在扫描过程中是会忽略掉这个类的,如下

@Aspect
@Component
public class Logger {

}

(2) 对上面的例子,基于xml配置的写法如下

@Aspect
public class Logger {

}

<!-- xml配置文件中 -->
<beans ...>
    <!-- 无论何种配置方式,不要忘了将切面类注册为spring的一个bean -->
    <bean id="logger" class="cn.example.spring.boke.Logger"></bean>
</beans>

(3) 由@Aspect注解标注的类,称之为切面类,与普通的类一样,都有成员方法与成员变量,不同的是,切面类还可以包含连接点,通知,引介等与AOP有关的东西

(4) 切面不能再被增强,如果想拿一个切面来增强另一个切面,是不可能的,Spring会将切面类从自动代理(auto-proxying)中排除

3.自定义一个切入点

(1) Spring AOP中的切入点目前只可能是bean中的方法,而对于一个普通类中的方法,是不可能成为切入点的,在Spring中,声明一个切入点主要包括两个部分:一个切入点签名以及一个切入点表达式,如下

//如下定义了一个叫做anyExampleAMethod的切入点,这个切入点会匹配cn.example.spring.boke包下的ExampleA类中的任何方法
//其中,(1)就代表的是切入点表达式,(2)就代表的是切入点签名,注意,这个签名的返回值必须是void
@Pointcut("execution(* cn.example.spring.boke.ExampleA.*(..))")      //(1)
public void anyExampleAMethod() {}                                   //(2)

(2) Spring AOP的切入点表达式中,支持如下等切入点标识符

  • execution:最为常用,用于匹配某个包,某个类中的方法

  • within:进行类型匹配,用于匹配某个包下所有类的所有方法或某个指定类中的所有方法,如下

//指定了within的类型,这个切入点会匹配cn.example.spring.boke包下ExampleA类中的任何方法
@Pointcut("within(cn.example.spring.boke.ExampleA)")
public void withinDesignator(){}
  • this:进行类型匹配,用于匹配生成的代理对象的类型是否为指定类型,如下
//此前我们提到过,Spring AOP中的底层实现分为jdk动态代理和cglib动态代理,jdk动态代理基于接口,要求目标对象必须实现某个接口,而cglib动态代理基于继承,因此不同的实现方式下,导致Spring生成的代理对象的类型可能不同,这就是this标识符的基础
//首先定义一个接口
public interface Parent {
    void register();

    void sendEmail();
}

//让我们的ExampleA类,实现这个接口
@Component
public class ExampleA implements Parent{

    public void register() {

    }

    public void sendEmail() {

    }
}

//设置@EnableAspectJAutoProxy注解中的proxyTargetClass属性值为false,表示使用jdk动态代理,为true,表示使用cglib动态代理,默认值为false,不过我们这里显式的声明出来
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ComponentScan(basePackages = "cn.example.spring.boke")
public class Config {

}

//切面类,在其中声明一个this标识符,并指定类型为ExampleA
@Aspect
@Component
public class Logger {
    /**
     * this标识符,进行类型匹配,用于匹配代理对象的类型是否为指定类型
     */
    @Pointcut(value = "this(cn.example.spring.bo
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇【深度思考】聊聊JDK动态代理原理 下一篇Java中「Future」接口详解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目