Spring AOP 切面编程的方法

spring aop的使用分为两种,一种是使用注解来实现,一种是使用配置文件来实现。

先来简单的介绍一下这两种方法的实现,接下来详细的介绍各处的知识点便于查阅。目录如下:

1.基于注解实现spring aop

2.基于配置文件实现spring aop

3.增强的分类

4.切点表达式的构成

1.基于注解来实现的方法

基于注解并不意味着不需要配置文件,只不过是在配置文件中所需要的配置很少。切面编程,显然我们需要一个增强类,一个被增强的普通类。

配置文件中需要添加以下的内容

xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=
"http://www.springframework.org/schema/aop
  http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"       <!--引入配置-->

<context:component-scan base-package="com.test.aspect"/>         <!--扫描这两个包-->
<context:component-scan base-package="com.test.user"/> 

<aop:aspectj-autoproxy/>  <!--开启aop自动扫描-->

下面是增强类

package com.test.aspect;

@Component@Aspect
public class TestAspect{
    @Before("execution(* com.test.user.Login.greetTo(..))")
     public void beforeDoing(){

          //do  somthing
    }
}

下面是被增强类

@Componentpublic Class Login{

   public void greetTo(){
      //some action
  }
}

这样就可以完成对被增强类的增强。

2.基于配置文件的方式

非注解方式的首先把上面的注解都去掉,主要内容在配置文件中,配置文件如下       (其实还有  <aop:advisor>的配置,不过是旧版本所用,如果spring版本较低使用)

xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=
"http://www.springframework.org/schema/aop
  http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"       <!--引入配置-->

<aop:config proxy-target-class="true">         <!--aop config 是最外层的内容-->
      <aop:pointcut id="pc" expression="execution(* com.test.aspect.*(..))"/>     <!--首先定义了切入点-->
      <aop:aspect ref="TestAspect" order="2">                                               <!--定义了增强类  order指的是增强织入的顺序-->
                <aop:before method="beforeDoing" pointcut-ref="pc"/>              <!--指定增强类中一个方法为before增强,切入点为之前定义的切入点-->
       </aop:aspect>
</aop:config>

 3.增强的分类

增强主要有以下几种:1.before  2.after 3.after-returning 4.after-throwing 5.around

依次进行一下介绍,提供注解方式和配置文件方式

// before 增强是在所需要增强的方法执行之前被织入

@before("execution(* org.test.*.*(..))")
public void beforeAction(JoinPoint jp)  //如果要使用joinpoint必须是第一个参数
{
     jp.getSignature().getName();  //获得目标方法
     jp.getArgs(); //获得目标方法的参数
     //dosomething
}

在配置文件中写成
<aop:before pointcut="execution(* org.test.*.*(..))" method="beforeAction"/>
//after 增强无论目标方法如何结束,都会织入在方法的后面

@After("execution(* org.test.*.*(..))")
public void afterAction(JoinPoint jp){

        //doSomething()

}

<aop :after pointcut="execution(* org.test.*.*(..))" method="afterAction">
//AfterReturning 将在目标方法正常完成后被织入

@AfterReturning(returning ="rvt" ,pointcut="execution(* org.test.*.*(..))")
public void log(JointPoint jp,Object rvt){
    //rvt是目标方法的返回值
}

<aop:after-returning pointcut="execution(* org.test.*.*(..))" method="log"/>
//afterthrowing 用于处理程序中未被处理的异常

@AfterThrowing(throwing="ex",pointcut="execution(* org.test.*.*(..))")
public void recovery(Throwable ex){

      //ex 是目标方法抛出的异常
}

<aop:after-throwing pointcut="execution(* org.test.*.*(..))" method="recovery" throwing="ex">
//round 功能比较强大,可以环绕被增强方法

@Around("execution(* org.test.*.*(..))")
public Object round(ProceedingJoinPoint pjp){
     Object[] args=jp.getArgs(); //获得参数
     Object rvt=jp.procceed(args);//调用目标方法,可以将修改后的参数传入
     return rvt+1;   //可以对返回值进行处理
}   

<aop:around pointcut="execution(* org.test.*.*(..))" method="round"/>

4.切点表达式的构成

//可以定义一个切点,然后后续重复使用,比较方便

@Pointcut("execution(* org.test.*.*(..))")
public void myPointcut(){}

@Before(pointcut="myPointcut")
public void before(){
      ....
}
//下面是配置文件方法中的对应内容
<aop:poincut id="myPointcut" expression=""execution(* org.test.*.*(..))""/>
<aop:aspect ref="TestAspect">
<aop:before method="before" pointcut-ref="myPointcut"/>

</aop:aspect>

之前所用的切点指示符只有 execution   还有 within this target  args  下面依次进行介绍

execution(1? 2 3? 4(5) 6?)
1.指定方法的修饰符 public private等,该部分可省略
2.指定方法的返回值  该部分不可省略 不过一般用*代表任意返回值
3.指定方法所属的类  可以省略,可用通配符
4.指定方法名,可用通配符,不可省略
5.指定方法的参数支持*与.. ()表示没有参数 (*)表示一个任意类型的参数 (..)表示任意数量的参数  (String,..)表示有一个String 参数,后面可以有任意个参数不可省略
6.指定方法声明要抛出的异常(throws) 可用通配符 可省略

eg.  execution(* org.test.service.impl.*.*(..))//org.test.service.imple 包下所有类的所有方法

pointcut="execution(* org.test.service.impl.*.*(..))"
//args 表示入参的类型 当入参类型匹配时织入 强调参数,可用execution代替
arg(Integer)

//within  类匹配模式
within(org.test.User)     //匹配User中的所有类,最小粒度,不能到方法
within(org.test.*)       //匹配org.test包中的所有类
within(org.test..*)       //匹配org.test包及子孙包中的所有类

//target和within类似,匹配符合的类别

//this判断代理对象的类是否匹配

//这几种都没怎么用过,所以简略提一下,用到后再补充

切点表达式也可以用复合的方式 && || !

用法很简单,而且个人感觉用处并不大...

@Before("A&&B")  AB均为之前描述的表达式  

如果在xml中配置则要用and or等     pointcut="A and B"

先写到这里,如果有需要补充的再来!

时间: 2024-12-24 23:27:47

Spring AOP 切面编程的方法的相关文章

Spring AOP 切面编程记录日志和接口执行时间

最近客户现在提出系统访问非常慢,需要优化提升访问速度,在排查了nginx.tomcat内存和服务器负载之后,判断是数据库查询速度慢,进一步排查发现是因为部分视图和表查询特别慢导致了整个系统的响应时间特别长.知道了问题之后,就需要对查询比较慢的接口进行优化,但哪些接口需要优化.哪些不需要呢?只能通过日志里的执行时间来判断,那么如何才能知道每一个接口的执行时间呢? 如果想学习Java工程化.高性能及分布式.深入浅出.微服务.Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级

spring AOP切面日志 拦截方法中有同名方法问题

代码: @ResponseBody @RequestMapping("/login.do") public Json login(SysUserPM sysUserPM, HttpSession session) { Json j = new Json(); SysUserPM sysUser = sysUserServiceI.doLogin(sysUserPM); if (sysUser != null) { System.out.println("后台用户登录成功!&q

Spring Aop 切面编程

需求:之前的动态选择数据库,和现在的将某个service层的方法接入cat,都需要用到切面编程. 参考文献: http://www.blogjava.net/supercrsky/articles/174368.html http://my.oschina.net/itblog/blog/211693 一.简介 面向切面编程(AOP)提供另外一种角度来思考程序结构,通过这种方式弥补了面向对象编程(OOP)的不足. 除了类(classes)以外,AOP提供了 切面.切面对关注点进行模块化,例如横切

AOP基础知识及AOP切面编程之注释方法、xml配置方法

<span style="font-family: 微软雅黑; font-size: 10.5pt; letter-spacing: 0pt; ">AOP概念</span> Aspect(切面):它跟类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面是对横切性关注点的抽象 joinpoint(连接点):所谓连接点就是被拦截到的点,在spring中,这些点是方法,因为spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器

Spring 面向切面编程(AOP)

Spring 系列教程 Spring 框架介绍 Spring 框架模块 Spring开发环境搭建(Eclipse) 创建一个简单的Spring应用 Spring 控制反转容器(Inversion of Control – IOC) 理解依赖注入(DI – Dependency Injection) Bean XML 配置(1)- 通过XML配置加载Bean Bean XML 配置(2)- Bean作用域与生命周期回调方法配置 Bean XML 配置(3)- 依赖注入配置 Bean XML 配置(

SPRING学习(十九)--基于注解的AOP切面编程

上篇中介绍了基于XML配置的AOP切面编程,除了XML配置AOP切面编程外,还可以通过注解方式实现AOP切面编程,本篇通过一个小例子来介绍基于注解的AOP编程. 1.在spring中使用AOP变成,不止要导入spring-aop.jar,还需要导入spring-aspects.jar.aspectjweaver.jar和aopalliance.jar,但是aspectjweaver.jar被spring-aspects.jar依赖,aopalliance.jar被spring-aop.jar依赖

Spring面向切面编程(二)简单AOP实例

简单实现一个用户登陆的功能,在用户登陆之前进行日志打印,用户登陆之后进行登陆成功日志打印. Maven添加Spring jar spring面向切面编程(一)AOP术语 添加Spring AOP的jar 参考:Maven添加Spring jar 还需添加: 创建User类: package com.user; public class User { private String username; private String password; public String getUsernam

Spring面向切面编程

  1.面向切面编程(AOP)的概念:把项目中需要在多处用到的功能,比如日志.安全和事物等集中到一个类中处理,而不用在每个需要用到该功能的地方显式调用.   2.术语解释:        横切关注点:分布应用于多处的功能        切面:横切关注点可以被模块化为一个类,这个类被称为一个切面        通知(advice):切面要完成的工作.Spring的通知有5种类型:before.after.after-returning.after-throwing和around这五种类型.    

AOP切面编程

AOP的实现底层实际上即为反射,JDK中的反射类java.lang.reflect.Proxy是Java中唯一可以访问调度器的类.类似地,常见的动态代理库cglib也是通过反射机制实现了动态代理的封装.技术成熟度相对较高的AspectJ和Spring AOP会在底层实现一套reflect机制,区别是两者对规范实现如何定义而已. 无论是AspectJ还是Spring AOP,所有这些AOP编程都是基于反射和运行时的动态代理控制实现的.下面通过Proxy和Cglib来实现自己的动态代理切面. 假设我