前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >AOP编程简介及其在Spring框架中的使用

AOP编程简介及其在Spring框架中的使用

作者头像
东溪陈姓少年
发布2020-08-06 15:14:48
7380
发布2020-08-06 15:14:48
举报
文章被收录于专栏:TECH flowerTECH flowerTECH flower

aop编程:

AOP与OOP互为补充,面向对象编程(OOP)将程序分解成各个层次的对象;面向切面编程(AOP)则是将程序运行过程中分解成各个切面。可以说OOP是从静态角度考虑程序结构而AOP是从动态角度考虑的。

AOP并不与某个具体类耦合。具有两个特性:

  1. 各步骤之间具有良好的隔离性
  2. 源代码无关性。

AOP的一些术语:

  1. 切面(aspect):切面用于组织多个advice,advice在切面中定义。
  2. 连接点(joinpoint):程序执行过程中明确的点,在spring中,连接点总是方法的调用。
  3. 增强处理(advice):AOP框架在特定切入点执行增强处理。
  4. 切入点(pointcut):可以插入增强处理的连接点。

本示例是使用基于注解的方式,另外还有基于xml的。

package Before;
//定义一个hello接口
public interface Hello {
//hello的两个方法
    public void foo();
    public int addUser(String name ,String pass);
}

package Before;

import org.springframework.stereotype.Component;
//注解component指定此为id为hello的bean
//实现接口并实现方法
@Component("hello")
public class HelloImpl implements Hello {

    @Override
    public void foo() {
        System.out.println("执行hello主键的foo方法");
    }

    @Override
    public int addUser(String name,String pass) {
        System.out.println("执行hello组键的adduser组键"+name);
        return 20;
    }

}

1.before增强处理

定义一个切面,定义一个before增强处理:

package Before;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

//定义一个切面
@Aspect
public class AuthAspect {

    //所有方法的执行作为切入点
    //括号中的是切入点表达式,文章最后进行介绍
    @Before("execution(* Before.*.*(..))")
    public void authority(){
        System.out.println("模拟进行权限检查");
    }
}

以下是spring配置文件:

<!--beans.xml spring的配置文件 -->
<?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-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
    <!-- 自动搜索Bean组件 自动搜索切面类 -->
    <context:component-scan base-package="Before">
        <context:include-filter type="annotation"
            expression="org.aspectj.lang.annotation.Aspect"/>
    </context:component-scan>
    <!-- 启动@AspectJ支持 -->
    <aop:aspectj-autoproxy/>
</beans>

ok,接下来我们来写一个测试类

package Before;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AspectTest {
    public static void main(String[] args) {
                // 创建Spring容器
                ApplicationContext ctx = new
                    ClassPathXmlApplicationContext("beans.xml");
                Hello hello = ctx.getBean("hello" , Hello.class);
                hello.foo();
                hello.addUser("孙悟空" , "7788");
    }
}

上面的所有步骤全部搞定,运行,结果如下

对比我们不进行AOP处理的结果:

结果很明显,这就是aop的作用,在不改动源代码的基础上,对源代码进行增强处理。


2.AfterReturning增强处理

AfterReturning有的属性值指定形参名,会限制目标方法必须有符合这两个形参。

package AfterReturning;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class LogAspect {
    @AfterReturning(returning="rvt", pointcut="execution(* Before.*.*(..)) && args(pass,name)")
    //声明rvt时指定的类型会限制目标方法必须有返回值或者没有返回值
    public void log(Object rvt,String pass,String name){
        System.out.println("第一个参数"+pass);
        System.out.println("第二个参数"+name);
        System.out.println("获取目标方法的返回值"+rvt);
        System.out.println("模拟记录日志功能。。。");
    }
}

结果(此结果加上before处理后的结果):


3.Afterthrowing增强处理

package AfterThrowing;

import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class RepairAspect {

    @AfterThrowing(throwing="ex",pointcut="execution(* Before.*.*(..))")
    public void doRecoveryActions11(Throwable ex){
        System.out.println("目标方法抛出的异常"+ex);
        System.out.println("模拟advice对异常的修复....");
    }
}

写一下前面的helloimpl类

package Before;

import org.springframework.stereotype.Component;

@Component("hello")
public class HelloImpl implements Hello {

    @Override
    public void foo() {
        System.out.println("执行hello主键的foo方法");
    }

    @Override
    public int addUser(String name,String pass) {
        System.out.println("执行hello组键的adduser组键"+name);
        if(name.length()<=3||name.length()>=10){
            throw new IllegalArgumentException("name的参数必须大于3小于10");
        }
        return 20;
    }

}

在xml文件中加入切面类所在的包,结果如下

可以看出,增强处理起作用了。


after增强跟before差不多,只不过一个在目标方法之前,一个在后。


4.Around增强处理

package Around;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class TxAspect{

    @Around("execution(* Before.*.*(..))")
    public Object processTx (ProceedingJoinPoint jp) throws Throwable{
        System.out.println("执行目标方法之前,模拟开始事务.....");
        //获取目方法原始的调用参数
        Object [] args=jp.getArgs();
        if(args!=null&&args.length>1){
            //修改目标方法调用参数的第一个参数
            args[0] ="【增加的前缀】"+args[0];
        }
        //以改变后的参数去执行目标方法,并保存目标方法返回的执行值
        Object rvt=jp.proceed(args);
        System.out.println("模拟事务结束........");
        if(rvt!=null&&rvt instanceof Integer){
            rvt=(Integer)rvt*(Integer)rvt;
        }
        return rvt;
    }
}

这个相对有点复杂,该类的方法processTx有个参数,就是代表目标方法,执行第一个输出之后,必须重新调用这个目标方法让他执行完再执第二个输出。

配置xml,后执行测试类

看到结果。和程序中描述的一样。


注: execution(* Before.*.*(..)) && args(pass,name) 第一个*表示目标方法的返回值任意。第二个 第三个表示 任意类的任意方法 &&后面的表示对连接点的参数类型进行限制,可以过滤目标方法。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 TECH flower 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • aop编程:
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档