【Spring入门-04】AOP

Spring AOP

AOP(Aspect Oriented Programming):面向切面编程,可以把各类的公共行为封装到一个可重用模块,并将其命名为 Aspect,即切面,减少系统的重复代码,降低模块之间的耦合。

常用的主要功能:日志记录,性能统计,安全控制,事务处理,异常处理。

相关术语

  • 通知(Advice):指拦截到连接点之后要执行的代码,通知又分为五种:
    • 前置通知(Before):在目标方法被调用之前调用通知
    • 后置通知(After):在目标方法完成之后调用通知
    • 返回通知(After-returning):在目标方法成功执行之后调用通知
    • 异常通知(After-throwing):在目标方法抛出异常后调用通知
    • 环绕通知(Around):在目标方法被调用前后执行通知
  • 连接点(Join point):指被拦截到的方法
  • 切点(Pointcut):对连接点进行拦截的定义
  • 切面(Aspect):是通知和切点的结合,是对横切关注点的抽象
  • 引入(Introduction):允许添加新方法或属性到现有的类中
  • 织入(Weaving):将切面应用到目标对象并创建新的代理对象的过程
    • 编译器:切面在目标类编译时被织入。这种方式需要特殊的编译器。AspectJ 就是以这种方式织入切面
    • 类加载期:切面在目标类加载到 JVM 时被织入。这种方式需要特殊的类加载器(ClassLoader),它可以在目标类被引入应用之前增强该目标类的字节码。AspectJ 5 的加载时织入(load-time weaving,LTW)就支持以这种方式织入切面
    • 运行期:切面在应用运行的某个时刻被织入。一般在织入切面时,AOP 容器会为目标对象动态创建一个代理对象。Spring AOP 就是以这种方式织入切面
  • 目标对象(Target object):被一个或者多个切面所通知的对象,这个对象永远是一个被代理对象

AspectJ 切点表达式

AspectJ 指示器描述
arg()限制连接点匹配参数为指定类型的执行方法
@args()限制连接点匹配参数由指定注解标注的执行方法
execution()用于匹配是连接点的执行方法
this限制连接点匹配 AOP 代理的 bean 引用为指定类型的类
target限制连接点匹配目标对象为指定类型的类
@target()限制连接点匹配由指定注解标注的执行对象
within()限制连接点匹配指定的类型
@within()限制连接点匹配指定注解标注的类型
@annotation限定匹配带有指定注解的连接点

通配符

  • * 匹配任意数量的字符
  • + 匹配指定类及其子类
  • .. 匹配任意数的子包或参数

运算符

  • &&and 与操作符
  • ||or 或操作符
  • !not 非操作符

使用注解声明切面

注解描述
@EnableAspectJAutoProxy启用自动代理功能
@AspectJ标注切面
@Pointcut标注可重用的切点
@After通知方法会在目标方法调用之后执行
@AfterReturning通知方法在目标方法返回后调用
@AfterThrowing通知方法在目标方法抛出异常后调用
@Around通知方法将目标方法封装起来
@Before通知方法会在目标方法调用之前执行

1. 声明切面

@Aspect:表明类 Audience 是一个切面。
@Pointcut:在切面内定义可重用的切点。
@Around:环绕通知必须接收一个 ProceedingJointPoint 参数。通过调用 ProceedingJointPointproceed() 方法调用被通知的目标方法,否则会阻塞对被通知目标方法的访问。

@Aspect
@Component
public class Audience {

    @Pointcut("execution(* com.chen.aop.Concert.perform(..))")
    public void performance(){
    }

    @Before("performance()")
    public void before(){
        System.out.println("Before performance.");
    }

    @After("performance()")
    public void after(){
        System.out.println("After performance.");
    }

    @AfterReturning("performance()")
    public void applause(){
        System.out.println("CLAP CLAP CLAP!!!");
    }

    @AfterThrowing("performance()")
    public void demandRefund(){
        System.out.println("Demanding a refund.");
    }
    
    @Around("performance()")
    public void log(ProceedingJoinPoint joinPoint){
        System.out.println("Log info.");
        try {
            joinPoint.proceed();
        } catch (Throwable throwable) {
            System.out.println("Log error.");
        }
    }
}

定义 Performance 接口及其实现类 Concert

public interface Performance {
    void perform();
}
@Component
public class Concert implements Performance {
    @Override
    public void perform() {
        System.out.println("Concert perform.");
        // throw new RuntimeException();
    }
}

2. 自动化装配 Bean

@EnableAspectJAutoProxy:启动自动代理功能。proxyTargetClass 默认为 false,表示使用JDK动态代理技术织入通知;当配置为 true 时,表示使用CGLib动态代理技术织入通知。

@EnableAspectJAutoProxy
@ComponentScan
public class ConcertConfig {
}

3. 测试

public class PerformanceTest {

    @Test
    public void test() {
        ApplicationContext context = new AnnotationConfigApplicationContext(ConcertConfig.class);
        Performance performance = context.getBean(Performance.class);
        performance.perform();
    }
}

使用 XML 配置声明切面

AOP 配置元素用途
<aop:advisor>定义 AOP 通知
<aop:after>定义 AOP 后置通知
<aop:after-returning>定义 AOP 返回通知
<aop:after-throwing>定义 AOP 异常通知
<aop:around>定义 AOP 环绕通知
<aop:aspect>定义一个切面
<aop:aspectj-autoproxy>启用 @AspectJ 注解驱动的切面
<aop:before>定义 AOP 前置通知
<aop:config>顶层的 AOP 配置元素
<aop:declare-parents>以透明的方式为被通知的对象引入额外的接口
<aop:pointcut>定义一个切点
<?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"
       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">

    <bean class="com.chen.aop.Concert"/>
    <bean id="audience" class="com.chen.aop.Audience"/>

    <aop:aspectj-autoproxy/>

    <aop:config>
        <aop:aspect ref="audience">
            <aop:pointcut id="performance" expression="execution(* com.chen.aop.Performance.perform(..))"/>

            <aop:before pointcut-ref="performance" method="before"/>
            <aop:after pointcut-ref="performance" method="after"/>
            <aop:after-returning pointcut-ref="performance" method="applause"/>
            <aop:after-throwing pointcut-ref="performance" method="demandRefund"/>
            <aop:around pointcut-ref="performance" method="log"/>
        </aop:aspect>
    </aop:config>

</beans>

Spring AOP 的两种代理方式

  1. 基于 JDK 接口的动态代理
  2. 基于 CGLib 动态生成子类的代理

如果目标对象实现了接口,则默认采用 JDK 动态代理
如果目标对象没有实现接口,则采用 CGLib 动态代理
如果目标对象实现了接口,且强制 CGLib 代理,则使用 CGLib 代理

Spring AOP 与 AspectJ 区别

Spring 在运行时通知对象
代理类封装了目标类,并拦截被通知方法的调用,再把调用转发给真正的目标类。
当代理拦截到方法调用时,在调用目标对象方法之前,会执行切面逻辑。

Spring 只支持方法级别的连接点
Spring 基于 JDK 动态代理,因此只支持方法连接点
AspectJ、JBoss 支持方法、字段和构造器连接点

应用

  • 事务 @Transational
  • 安全校验 @PreAuthorize
  • 缓存 @Cacheable

参考

  1. GitHub 代码
  2. Spring框架小白的蜕变
  3. 探秘Spring AOP
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
**数字乡村解决方案摘要** **国家战略与乡村振兴** 中国正实施国家大数据战略,以加快数字中国的建设,整合数据资源,保障数据安全,并推动产业升级。2023年中央一号文件强调了乡村振兴战略,旨在通过产业兴旺、生态宜居、乡风文明、治理有效和生活富裕五大方面,实现农业农村现代化。 **数字乡村建设的重要性** 数字乡村建设是乡村振兴战略的重要组成部分,通过整合资源数据,推动物联网和遥感技术在农业中的应用,促进农业现代化。它被视为促进乡村转型发展的新方向,是数字化在农业农村经济社会发展中的应用。 **关键要素与效益** 数字乡村建设的关键要素包括数据资源整合、产业促进、农业发展规模化和标准化,以及改善乡村生活服务体系。预期效益包括提升国家治理能力,实现政府决策科学化和社会治理精准化,同时推动公共服务高效化。 **体系架构与数据融合** 数字乡村的体系架构包括乡村生态、基层治理、慧治、慧享、慧融、慧美、慧智和慧图等多个方面,实现城乡、政企、农户各级平台及服务的融合。数据融合是核心,整合乡村人口、产值、环境监测等多方面数据,为乡村治理和产业发展提供支撑。 **多业务协同与智慧治理** 数字乡村通过多业务协同应用平台,实现乡村物联网的布局和触达,涵盖农业生产、农资厂商、消费者等环节。区块链技术在农产品质量溯源中的应用,确保了产品全过程可追溯。乡村智慧治理通过村务管理、财务管理等方面提升治理效能,实现绿色发展理念。综合服务体系通过“互联网+服务”模式,提供便民服务和乡村经济发展支持,推动乡村全面振兴。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值