LOFTER for ipad —— 让兴趣,更有趣

点击下载 关闭
Spring个人笔记Part3
Nowakii 2018-09-17

AOP 为 Aspect Oriented Programming 的缩写,称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等。AOP 采取横向抽取机制,将分散在各个方法中的重复代码提取出来,然后在程序编译或者运行时,再将这些提取出来的代码应用到需要执行的地方。AOP 的本质是拦截方法的,对方法进行增强。如何增强? 通过代理-------所以 AOP 的本质就是代理。


AOP 的基本概念:

(1)Aspect(切面):通常是一个类,里面可以定义切入点和通知

(2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用

(3)Advice(通知):AOP 在特定的切入点上执行的增强处理,有

before,after,afterReturning,afterThrowing,around

(4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式

(5)AOP 代理:AOP 框架创建的对象,代理就是目标对象的加强。Spring 中的 AOP 代理可以使 JDK 动态代理,也可以是 CGLIB 代理,前者基于接口,后者基于子类。

JDK 动态代理

JDK 动态代理是通过 java.lang.reflect.Proxy 类来实现的,我们可以调用 Proxy 类

的 newProxyInstance()方法来创建代理对象。对于使用业务接口的类,Spring 默认会使

用 JDK 动态代理来实现 AOP。

重点:XML配置(最常用)

AspectJ 开发AspectJ 是一个基于 Java 语言的 AOP 框架,它提供了强大的 AOP 功能,aspectj不是 spring 一部分。使用 AspectJ 实现 AOP 有两种方式:一种是基于 XML 的声明式 AspectJ,一种是基于注解的声明式 AspectJ。


  • 栗子:

  • 创建一个实体类User,给他添加一个add方法和num方法。

public class User {

public void add(){

System.out.println("添加");

}

public int num(int a,int b){

int result=a/b;

return result;

}

}

  • 给user创建一个实现类Myuser

    public class Myuser {

    public void before(){

    System.out.println("前置增强");

    }

    //后置增强

    public void after(){

    System.out.println("后置增强");

    }

    //环绕通知必须携带proceedJoinpoint类型参数  ,该参数可以决定是否执行目标方法

    //加上thorws Throwable

    //方法是object返回类型

    public Object around(ProceedingJoinPoint point) throws Throwable{

    //方法前

    System.out.println("方法前");

    Object obj=point.proceed();//获取目标方法

    //方法后

    System.out.println("方法后");

    return obj;

    }

    public void deException(Exception e){

    System.out.println("异常通知"+e.getMessage());

    }

    public void returnAfter(Object result){

    System.out.println("最终通知"+result);

    }

    }

    创建前置增强方法,后置增强方法,环绕类,异常类,最终通知类。

  • 配置XML文件

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="https://www.springframework.org/schema/beans"

xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"

xmlns:aop="https://www.springframework.org/schema/aop"

xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd

https://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop-4.1.xsd">

<!-- 配置bean -->

<bean id="user" class="com.hpe.bean.User"></bean>

<bean id="myuser" class="com.hpe.bean.Myuser"></bean>

<!-- 配置AOP -->

<aop:config>

<!-- 切入点 -->

<aop:pointcut expression="execution(* com.hpe.bean.User.*(..))" id="user1"/>

<!-- 配置切面 -->

<aop:aspect ref="myuser">

<!-- 配置增强的类型 -->

<!-- 前置通知 -->

<aop:before method="before" pointcut-ref="user1"/>

<!-- 后置通知   即使方法是错误的 也会执行-->

<aop:after method="after" pointcut-ref="user1"/>

<!-- 环绕 -->

<aop:around method="around" pointcut-ref="user1"/>

<!-- 异常通知 -->

<aop:after-throwing method="deException" pointcut-ref="user1" throwing="e"/>

<!-- 最终通知  在方法正确时 -->

<aop:after-returning method="returnAfter" pointcut-ref="user1" returning="return"/>

</aop:aspect>

</aop:config>

</beans>

首先配置bean,使用User实体类id和class的全类名,Myuser的id和全类名。

  • 然后配置AOP 使用<aop:config>标签

    配置切入点pointcut  注意expression=“execution(*com.xxx.bean.user.*(..))”括号内表示参数类型,*表示下级的全部内容。

    配置切面<aop:ascept   ref=“代理类的id”>

    配置增强类型

    前置(before)

    后置(after)即使代码是错误的也会执行

    环绕(around)我也不知道为什么不是surround


  • 异常通知(after-throwing)  只有在代码产生异常时才会运行

  • 最终通知(after-returning)只有在方法正确时才会运行


以上这些都需要设定切入点pointcut-ref=”切入点的id“

其中异常和最终通知可以添加参数,分别为获取错误的变量和获取的返回值。

而且都需要包含在<aop:aspect>和<aop:config>之中



 

推荐文章
评论(0)
分享到
转载我的主页