AOP面向切面

1、编程方式

        POP 面向过程编程
        面向过程编程(Procedure Oriented Programming)是以功能为中心来进行思考和组织的一种编程方法,它强调的是系统的数据被加工和处理的过程,在程序设计中主要以函数或者过程为程序的基本组织方式,系统功能是由一组相关的过程和函数序列构成。
        OOP 面向对象编程
        面向对象编程(Object Oriented Programming)依然保留着面向过程的特性,面向过程中的功能变成了对象的方法,业务逻辑功能变成了对象的方法,而这部分方法依然需要提供获取操作,同时也对提供写入操作,只是获取与写入也变成了对象。
        AOP 面向切面编程
        面向切面编程(Aspect Oriented Programming)是对于 OOP 的补充和完善。OOP 引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP 则显得无能为力。也就是说,OOP 允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在 OOP 设计中,它导致了大量代码的重复,而不利于各个模块的重用。

2、代理模式

        代理是设计模式的一种,代理类为委托类提供消息预处理,消息转发,事后消息处理等功能。

        静态代理

        Java 中的静态代理要求代理类委托类都实现同一个接口。静态代理中代理类在编译期就已
经确定,而动态代理则是 JVM 运行时动态生成,静态代理的效率相对动态代理来说相对高一些,
但是静态代理代码冗余大,一旦需要修改接口,代理类和委托类都需要修改。

        动态代理

        Java 中的动态代理依靠反射来实现,代理类和委托类不需要实现同一个接口。委托类需要实
现接口,否则无法创建动态代理。代理类在 JVM 运行时动态生成,而不是编译期就能确定。

        1、JDK代理

        在程序运行的过程中通过java反射机制生成动态代理类,并实现委托类所实现的接口。

        2、CGLIB代理

        在程序运行的过程中通过ASM字节码修改(类装载机制:class文件不能修改,但cglib可以)

        3、代理切换

        aop采用动态代理默认值 采用jdk代理

        aop设置动态代理为cglib代理 采用cglib代理

        aop设置动态代理为jdk代理,但委托未实现接口 自动切换至cglib代理

3、实现方式

        在配置之前需要先在pom.xml中引入maven依赖

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>版本号</version>
        </dependency>

        1、基于配置

<!-- 配置扫描 -->
<context:compoent-scan base-package="com.zhang.spring"/>

<!-- Aop动态代理 -->
<aop:comfig>
    <!--声明aop切面-->
    <aop:aspect ref="需要执行的类,首字母小写">
        <!--声明切入点匹配类型方法-->
        <aop:pointcut id="methodPointcut" expression="execution(返回值类型 项目名+模块名+接口/方法名+参数类型)"/>
        <!--例如:execution(* com.zhang.spring.aop.service.AopService.query(String,int))-->
        <!--绑定执行方法名称及切入点类型-->
        <aop:after method="需要执行的方法" pointcut-ref="methodPointcut"/>
    </aop:aspect>
</aop:comfig>

        2、基于注解

<!--配置扫描范围,扫描范围内的所有注解(@Controller、@Service、@Repository、@Component)-->
<context:component-scan base-package="com.zhang.spring:/>

<!--启用aop注解支持-->
<aop:aspectj-autoproxy/>
//声明切面
@Aspect
//添加注解,实例化此类
@Component
public void AnnotationText{
    
    //声明切入点,拦截service下所有的所有(任意返回值,任意参数个数及类型,任意名称)方法
    @Pointcut("execution(* com.zhang.service.*(..))")
    public void methodPointCut(){}

    //绑定拦截后方法(可以是其他)
    @After("methodPointCut()")
    public void method(){
        System.out.print("hello word");
    }
}

4、通知指示符

1、通知类型

        1、before前置通知

        在拦截方法之前执行,与程序是否异常无关

        2、after-returning成功通知

        在拦截方法执行成功后通知

        3、after-trhowing异常通知

        在拦截方法抛出异常后通知

        4、after结束通知

        在拦截方法执行结束后通知,无论程序是否执行成功

        5、around环绕通知

        在拦截方法执行前后均执行。前置工作完成后需要放行,拦截方法返回值需要return

2、通配符

         *  匹配任意数量的字符,可以代表任意类型的返回值,模块名、类名、方法名。

<aop:pointcut id="method" expression="execution(* com.zhang.spring.*.service.impl.*.*())"/>

         +  匹配所有目标的子类

<aop:pointcut id="method" expression="within(com.javakc.zhang.aop.service.AopService+)"/>

        ..  匹配任意包数量,任意参数类型及数量

        execution

        用于匹配执行方法的连接点

<aop:pointcut id="method" expression="execution(* com.zhang.spring.*.service.impl.*.*(..))"/>

        within

        within比较严格,他是严格匹配被代理对象类型的,不会理会继承关系。

<aop:pointcut id="method" expression="within(com.zhang.spring.aop.service.AopService+)"/>

        this

        匹配当前aop代理对象的执行方法,注意是aop代理对象的类型匹配,这样就可能包括引入接口方法也可以匹配。注意this中使用的表达式必须是类型全限定名,不支持通配符。

<aop:pointcut id="method" expression="this(com.zhang.spring.aop.service.AopService)"/>

        target

        匹配当前目标对象类型的执行方法,注意是目标对象类型匹配,这样就不包括引入接口也类型匹配。注意target中使用的表达式必须是类型全限定名,不支持通配符。

<aop:pointcut id="method" expression="target(com.zhang.spring.aop.service.AopService)"/>

        args

        匹配当前执行方法传入的参数类型指定类型的执行方法,不支持通配符,开销非常大。

<aop:pointcut id="method" expression="args(String, ..)"/>

5、常用注解

@Aspect声明切面
@Order多个切面见排序,数字越小优先级越高
@Pointcut声明切入点,定义拦截规则,用于获取需要通知实现的方法
@Before在目标方法执行之前执行执行的通知
@After在目标方法执行之后执行的通知
@AfterThrowing在目标方法抛出异常时执行的通知
@AfterReturning是在目标方法执行之后执行的通知
@Around在目标方法执行之前和之后都可以执行额外代码的通知
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值