Spring框架之AOP

什么是AOP

AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码降低模块间的耦合度,并有利于未来的可拓展性和可维护性

Spring AOP就是基于动态代理的(关于动态代理的内容我们已经在MyBatis(三)动态代理中介绍过了)如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用Cglib ,这时候Spring AOP会使用 Cglib 生成一个被代理对象的子类来作为代理,如下图所示:

SpringAOPProcess

当然你也可以使用 AspectJ ,Spring AOP 已经集成了AspectJ ,AspectJ 应该算的上是 Java 生态系统中最完整的 AOP 框架了。

AOP中的基本概念

Joinpoint(连接点):指那些被拦截的点,在spring中,这些点指的是方法,因为spring只支持方法的连接点,类中的方法可以被增强,这些方法称之为连接点。

Pointcut(切入点):指我们要对哪些Joinpoint进行拦截的定义,在类中可以有很多方法被增强,实际增强的方法称之为切入点。

 Advice(通知/增强):指拦截到Joinpoint之后要做的事情就是通知,通知分为:前置通知、后置通知、异常通知、最终通知、环绕通知:

  • 前置通知:在方法调用前执行
  • 后置通知:在方法调用后执行
  • 异常通知:在方法调用出现异常时调用
  • 最终通知:在方法调用后且后置通知之后执行
  • 环绕通知:在方法调用前后执行

Aspect(切面):把增强应用到切入点的过程。

Introduction(引介):引介是一种特殊的通知在不修改代码的前提下,Introduction可以在运行期为类动态的添加一些方法或Field。

Traget(目标对象):代理的目标对象(要增强的类)。

Weaving(织入):是把增强应用到目标的过程,把advice应用到target的过程。

Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类。

AOP实现

   AOP的实现也有两种方式:XML配置和注解,我们先介绍XML配置的方式:

1、XML实现AOP

(1) AOP依赖的jar包(在对应的pom文件中添加相关依赖) 

<!--AOP相关jar包-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.6.0</version>
    </dependency>
    <dependency>
      <groupId>aopalliance</groupId>
      <artifactId>aopalliance</artifactId>
      <version>1.0</version>
    </dependency>

(2)增加AOP相关的约束

<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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop.xsd">

</beans>

(3)创建student类和增强类

package com.tulun;

public class Student1 {
	
	//add方法
	public void add(){
      System.out.println("Student的add方法");
      }
}

 

public class AddAdvice { 
    public void addBefore(){
        System.out.println("addBefore");
    }

(4)配置XML文件(SpringAOP.xml)
 此处介绍如何用表达式来配置切入点
         在通知中通过value属性定义切入点,通过execution函数,可以定义切入点的方法切入
 1、切入点:实际增强的方法
 2、常用的表达式
 execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
  (1)execution(* com.tulun.bean.Student1.show(..)) 表类里面的某一个方法
  (2)execution(* com.tulun.bean.Student1.*(..)) 表类某个包里类所有方法
  (3)execution(* *.*(..))   表示所有
例:
 -匹配所有类public方法 execution(public *.*(..))
 -匹配指定包下所有类方法 execution(* com.tulun.bean.*(..)) (不包含子包)
 - execution(* com.tulun.bean..*(..)) (包含包、子包下所有类)
 -匹配指定类所有方法 execution(* com.tulun.bean.Book.*(..))
 -匹配实现特定接口所有类方法 execution(* com.tulun.bean.Book+.*(..))
 -匹配所有com开头的方法 execution(* com*(..))

 <!--配置对象-->
    <bean id="student" class="com.tulun.bean.Student1"/>
    <bean id="log" class="com.tulun.bean.AddAdvice"/>

    <!--配置AOP操作-->
    <aop:config>
        <!--配置切入点:通过表达式实现-->
        <aop:pointcut id="a" expression="execution(* com.tulun.bean.Student1.add(..))"/>

        <!--配置切面:把增强用到方法上-->
        <aop:aspect ref="AddAdvice" >
            <!--配置增强类:使用的前置增强-->
            <aop:before method="addBefore" pointcut-ref="a"/>
        </aop:aspect>
    </aop:config>

(5)进行测试调用:

 ApplicationContext context = new ClassPathXmlApplicationContext("SpringAOP.xml");
  Student1  student = (Student1)context.getBean("student");
  student.add();

2、注解实现AOP

(1)、在XML配置创建对象

 <!--配置对象-->
    <bean id="student" class="com.tulun.bean.Student1"/>
    <bean id="log" class="com.tulun.bean.AddAdvice"/>

(2)、开启AOP操作

 <!--开启AOP操作:注解方式使用-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

(3)、在增强类上添加注解,在增强类方法上添加通知的注解

/**
 * 增强类
 */
@Aspect 
//@Aspect 配置在类上,配置在增强类上
public class AddAdvice {
    //前置增强
    //Before前置通知标签,需要配置在方法, value属性值是通过execution表达式来配置切入点
    @Before(value = "execution(* com.tulun.bean.Student1.add(..))")
    public void beforeAdvice(){
        System.out.println("前置增强");
    } 
}

   以上关于AOP的两种实现方式,都是一些很简单的过程,如果需要深入还是应该多看看源码,基于老式的xml文件的实现,不推荐我们这样做,为什么?当系统大了之后,那系统中将会有很多的beanxml文件,这不容易维护和管理,我建议采用基于注解的方式进行AOP编程会更好。

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值