Spring 学习(三)AOP

时间:2023-02-17 22:11:07

(1)AOP概述

  - AOP:面向切面编程,扩展功能不修改源代码实现

  - AOP采取横向抽取机制,取代了传统的纵向继承体系重复性代码

(2)AOP底层原理

  原始方法-------》纵向继承体系

      Spring 学习(三)AOP

  横向机制:

JDK代理机制:jdk动态代理是由Java内部的反射机制来实现的.jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。

CGlib代理机制:Cglib的原理是对指定的目标类动态生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类和final方法进行代理。

       Spring 学习(三)AOP

 

(3)AOP操作相关术语(重点切入点、增强、切面)

spring的AOP操作(基于aspectj的XML方式)

Joinpoint   连接点:类里面可以被增强的方法,这些方法称为连接点

Pointcut     切入点:在类里面可以有很多的方法被增强,但是在实际的操作中值只是增强了add()和update(),则这两个实际增强的方法称为切入点

Advice      通知/增强:实际增强的逻辑,称为增强,例如扩展日志的功能,这个日志功能称为增强

      分为:

(1)前置通知:在方法之前执行

     (2)后置通知:在方法之后执行

     (3)异常通知:方法出现异常

     (4)最终通知:在后置之后执行

     (5)环绕通知:在方法之前和方法之后都执行,例如获取执行时间

 Aspect      切面:把我们的Advice增强应用到具体的Pointcut切入点方法上面,这个过程称为切面

Introduction  引介 :是一种特殊的增强,它为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过AOP的引介功能,我们可以动态地为该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。

Target        目标对象增强逻辑的织入目标类。如果没有AOP,目标业务类需要自己实现所有逻辑,而在AOP的帮助下,目标业务类只实现那些非横切逻辑的程序逻辑,而性能监视和事务管理等这些横切逻辑则可以使用AOP动态织入到特定的连接点上。
Weaving   织入织入是将Advice增强添加对target目标类具体连接点上的过程。AOP像一台织布机,将目标类、增强或引介通过AOP这台织布机天衣无缝地编织到一起。根据不同的实现技术,AOP有三种织入的方式:
    a、编译期织入,这要求使用特殊的Java编译器。
    b、类装载期织入,这要求使用特殊的类装载器。
    c、动态代理织入,在运行期为目标类添加增强生成子类的方式。
    Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。

proxy        代理:一个类被AOP织入增强后,就产出了一个结果类,它是融合了原类和增强逻辑的代理类。根据不同的代理方式,代理类既可能是和原类具有相同接口的类,也可能就是原类的子类,所以我们可以采用调用原类相同的方式调用代理类。

(4)Spring的AOP操作

1、在spring里面进行AOP操作,使用 AspecJ  实现

  AspectJ:面向切面的框架,它扩展了JAVA语言,是一个基于JAVA语言的AOP框架

  - (1)aspectj不是spring的一部分,和spring一起使用进行AOP操作

  - (2)Spring2.0之后新增加了对 aspectj 支持

2、使用AspectJ 方式实现AOP操作有两种方式

  - (1)基于AspectJ 的xml配置

Book类:

package cn.itcast.aop;

public class Book {
public void add(){
System.out.println("add book......");
} }

MyBook类:增强类对象

package cn.itcast.aop;

import org.aspectj.lang.ProceedingJoinPoint;

//增强类
public class MyBook {
public void befoer1(){
System.out.println("前置before1......");
}
public void after1(){
System.out.println("后置after1......");
}
//环绕通知
public void around1(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
//在方法之前执行
System.out.println("方法之前执行....."); //执行被增强的方法
proceedingJoinPoint.proceed(); //在方法之后执行
System.out.println("方法之后执行....");
}
}

AspectJ 的xml配置:

<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here --> <!--1、 配置对象 -->
<bean id="book" class="cn.itcast.aop.Book"></bean>
<bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
<!-- 2、配置AOP操作 -->
<aop:config>
<!-- 2.1 配置切入点 -->
<aop:pointcut expression="execution(* cn.itcast.aop.Book.add(..))" id="pointcut1"/>
<!-- 2.2配置切面 :把增强用到方法上面 -->
<aop:aspect ref="myBook">
<!-- 配置增强类型 :method:增强的类里面,使用哪个方法作为前置增强-->
<aop:before method="befoer1" pointcut-ref="pointcut1"/>
<aop:after-returning method="after1" pointcut-ref="pointcut1"/>
<aop:around method="around1" pointcut-ref="pointcut1"/> </aop:aspect>
</aop:config>
</beans>

测试代码:

    public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("aopbeans.xml");
Book book=(Book)context.getBean("book");
book.add();
}

结果:

前置before1......
方法之前执行.....
add book......
方法之后执行....
后置after1......

 - (2)基于aspectj 的注解方式

    - 第一步:在配置文件中设置对象

<bean id="book" class="cn.sdust.aop.Book"></bean>
<bean id="myBook" class="cn.sdust.aop.MyBook"></bean>

    - 第二步:开启aop操作

    <!-- 开启aop操作 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    - 第三步:在增强类上面使用注解完成AOP操作

Book类

package cn.sdust.aop;

public class Book {

    public void add(){
System.out.println("add book.....");
}
}

MyBook类

package cn.sdust.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; @Aspect
public class MyBook {
//在方法上面使用注解完成增强配置
@Before(value="execution(* cn.sdust.aop.Book.*(..))")
public void before(){
System.out.println("before......");
}
@AfterReturning(value="execution(* cn.sdust.aop.Book.*(..))")
public void after(){
System.out.println("after......");
}
@Around(value="execution(* cn.sdust.aop.Book.*(..))")
public void round(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("round--before....");
proceedingJoinPoint.proceed();
System.out.println("round--after....");
}
}

xml配置文件

<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here --> <!-- 开启aop操作 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 创建对象 -->
<bean id="book" class="cn.sdust.aop.Book"></bean>
<bean id="myBook" class="cn.sdust.aop.MyBook"></bean>
</beans>

测试代码

    @Test
public void testaop(){
ApplicationContext context=new ClassPathXmlApplicationContext("aop.xml");
Book book=(Book) context.getBean("book");
book.add();
}

运行结果

round--before....
before......
add book.....
round--after....
after......

AOP 操作准备:

1、jar包

  - 基本jar包

  Spring 学习(三)AOP

  - aspectj 的jar 包

  Spring 学习(三)AOP

 2、xml中的约束有beans、context、aop

Spring 学习(三)AOP

<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here --> </beans>

使用表达式配置切入点

  1、切入点:实际增强的方法

  2、常用表达式

  execution (<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)

  (1)execution (* com.skd.aop.Book.add(..))//其中的(1)*表示修饰符(2)..表示如果有参数,也包括

  (2)execution (* com.skd.aop.Book.*(..)) //Book/类的所有方法

  (3)execution (* *.*(..))//所有类的所有方法

  (4)execution (* save*(..)) //匹配save开头的所有方法

Spring 学习(三)AOP的更多相关文章

  1. Spring学习之AOP的实现方式

    Spring学习之AOP的三种实现方式 一.介绍AOP 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能 ...

  2. spring学习&lpar;三&rpar; ———— spring事务操作

    前面一篇博文讲解了什么是AOP.学会了写AOP的实现,但是并没有实际运用起来,这一篇博文就算是对AOP技术应用的进阶把,重点是事务的处理. --wh 一.jdbcTemplate 什么是JdbcTem ...

  3. spring学习&lpar;二&rpar; ———— AOP之AspectJ框架的使用

    前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...

  4. Spring学习之AOP总结帖

    AOP(面向方面编程),也可称为面向切面编程,是一种编程范式,提供从另一个角度来考虑程序结构从而完善面向对象编程(OOP). 在进行 OOP 开发时,都是基于对组件(比如类)进行开发,然后对组件进行组 ...

  5. spring框架学习&lpar;三&rpar;——AOP&lpar; 面向切面编程&rpar;

    AOP 即 Aspect Oriented Program 面向切面编程 首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能. 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务 ...

  6. Spring学习之Aop的基本概念

    转自:http://my.oschina.net/itblog/blog/209067 AOP的基本概念 AOP从运行的角度考虑程序的流程,提取业务处理过程的切面.AOP面向的是程序运行中的各个步骤, ...

  7. Spring学习之AOP与事务

      一.概述 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续, ...

  8. Spring学习三

    Spring注解来注入bean 在classpath中扫描组件 组件扫描,即componetscanning 利用注解来扫描的组件有  @Component  :基本注解,表示一个受Spring管理的 ...

  9. Spring 学习二-----AOP的原理与简单实践

    一.Spring  AOP的原理 AOP全名Aspect-Oriented Programming,中文直译为面向切面(方面)编程.何为切面,就比如说我们系统中的权限管理,日志,事务等我们都可以将其看 ...

  10. Spring学习之&equals;&equals;&gt&semi;AOP

    一.概述 AOP(Aspect Oriented Programming)称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等,Struts2的拦截器设计就是基于A ...

随机推荐

  1. 关于成为Java高级工程师之路

    简单说明一下现状,个人目前学习使用java已经一年半,很迷茫,高不成低不就,在此列一个目标,为期18个月,再来个一年半,这样软件生涯三年后,我必须成为高级工程师! 这里涉及Java各个方面的知识,有的 ...

  2. 关于 unsigned 型变量在计算过程中发生的事情

    运行环境:CentOS release 5.8 (Final) #include<stdio.h> #include<iostream> using namespace std ...

  3. show status和show variables区别解析

    1.show status    查看系统运行的实时状态,便于dba查看mysql当前运行的状态,做出相应优化,动态的,不可认为修改,只能系统自动update. MariaDB [(none)]&gt ...

  4. hdu 4664 Triangulation 博弈论

    看到这题时,当时还不会做,也没搞懂sg函数,于是狠狠的钻研了下博弈论,渐渐的知道了sg函数…… 现在在来做这题就很容易了,1A 打表容易发现在80左右的时候就出现循环节了 代码如下: #include ...

  5. &lbrack;ios2&rsqb;如何让IOS应用从容地崩溃 【转】

    文/donglin 虽然大家都不愿意看到程序崩溃,但可能崩溃是每个应用必须面对的现实,既然崩溃已经发生,无法阻挡了,那我们就让它崩也崩得淡定点吧. IOS SDK中提供了一个现成的函数 NSSetUn ...

  6. FZU 1062 洗牌问题

    首先有一个规律:当一个数字归位的时候,所有数字都会归位. 因此只需要模拟一个数字就可以了. #include<cstdio> #include<cstring> #includ ...

  7. window&period;open&lpar;&rpar;被拦截问题

    最近做项目的时候遇到一个需求,在商品详情页面中点击购买按钮,之后再新标签页中打开生成的订单页面,所以想用window.open()来实现.但是测试的时候发现打开的链接被浏览器拦截. 之后,开始在网上查 ...

  8. Spring 进入Controller前参数校验

    在进入Controller前完成参数的校验,针对对象参数 分为两个验证方式 (1)直接使用已定义的校验方式 1.在需要进行校验的属性上增加校验类型注解 import java.util.Date; i ...

  9. Linux命令 printf

    定长: $ printf '%s\t%s\t%s\t%s\t%s\t\n' $(cat printf.txt) # %s 表示一个不固定长度的字符串:printf不是管道命令,因此需要通过类似cat的 ...

  10. cmd下PUSHD和POPD命令使用说明

    PUSHD命令保存当前目录以供 POPD 命令使用,然后改到指定的目录. PUSHD [path | ..] path 指定要成为当前目录的目录. 如果命令扩展被启用,除了一般驱动器号和路径,PUSH ...