技术分析之Spring框架的核心功能之AOP技术

AOP的概述
    
    1. 什么是AOP的技术?
        * 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程
        * AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构
        * AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范
        * 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术
        * AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
        * 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率
    
    2. AOP:面向切面编程.(思想.---解决OOP遇到一些问题)
    3. AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)
    
    4. 为什么要学习AOP
        * 可以在不修改源代码的前提下,对程序进行增强!!

Spring框架的AOP的底层实现
    
    1. Srping框架的AOP技术底层也是采用的代理技术,代理的方式提供了两种
        1. 基于JDK的动态代理
            * 必须是面向接口的,只有实现了具体接口的类才能生成代理对象
        
        2. 基于CGLIB动态代理
            * 对于没有实现了接口的类,也可以产生代理,产生这个类的子类的方式
    
    2. Spring的传统AOP中根据类是否实现接口,来采用不同的代理方式
        1. 如果实现类接口,使用JDK动态代理完成AOP
        2. 如果没有实现接口,采用CGLIB动态代理完成AOP

    
JDK的动态代理(代码了解,理解原理)
    
    1. 使用Proxy类来生成代理对象的一些代码如下:

 /**
* 使用JDK的方式生成代理对象
* @author Administrator
*/
public class MyProxyUtils {
public static UserDao getProxy(final UserDao dao) {
// 使用Proxy类生成代理对象
UserDao proxy = (UserDao) Proxy.newProxyInstance(dao.getClass().getClassLoader(),
dao.getClass().getInterfaces(), new InvocationHandler() { // 代理对象方法一直线,invoke方法就会执行一次
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("save".equals(method.getName())){
System.out.println("记录日志...");
// 开启事务
}
// 提交事务
// 让dao类的save或者update方法正常的执行下去
return method.invoke(dao, args);
}
});
// 返回代理对象
return proxy;
}
}

CGLIB的代理技术(代码了解)
    
    1. 引入CBLIB的开发包
        * 如果想使用CGLIB的技术来生成代理对象,那么需要引入CGLIB的开发的jar包,在Spring框架核心包中已经引入了CGLIB的开发包了。所以直接引入Spring核心开发包即可!
    
    2. 编写相关的代码

public static OrderDaoImpl getProxy(){
// 创建CGLIB核心的类
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(OrderDaoImpl.class);
// 设置回调函数
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
if("save".equals(method.getName())){
// 记录日志
System.out.println("记录日志了...");
}
return methodProxy.invokeSuper(obj, args);
}
});
// 生成代理对象
OrderDaoImpl proxy = (OrderDaoImpl) enhancer.create();
return proxy;
}

 Spring基于AspectJ的AOP的开发

**技术分析之AOP的相关术语**
    
    1. Joinpoint(连接点)    -- 所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点
    2. Pointcut(切入点)        -- 所谓切入点是指我们要对哪些Joinpoint进行拦截的定义
    3. Advice(通知/增强)    -- 所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
    4. Introduction(引介)    -- 引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field
    5. Target(目标对象)        -- 代理的目标对象
    6. Weaving(织入)        -- 是指把增强应用到目标对象来创建新的代理对象的过程
    7. Proxy(代理)        -- 一个类被AOP织入增强后,就产生一个结果代理类
    8. Aspect(切面)            -- 是切入点和通知的结合,以后咱们自己来编写和配置的
    

    
技术分析之AspectJ的XML方式完成AOP的开发
    
    1. 步骤一:创建JavaWEB项目,引入具体的开发的jar包
        * 先引入Spring框架开发的基本开发包
        * 再引入Spring框架的AOP的开发包
            * spring的传统AOP的开发的包
                * spring-aop-4.2.4.RELEASE.jar
                * com.springsource.org.aopalliance-1.0.0.jar
            
            * aspectJ的开发包
                * com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
                * spring-aspects-4.2.4.RELEASE.jar
    
    2. 步骤二:创建Spring的配置文件,引入具体的AOP的schema约束

 <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">   

3. 步骤三:创建包结构,编写具体的接口和实现类
        * com.itheima.demo2
            * CustomerDao            -- 接口
            * CustomerDaoImpl        -- 实现类
    
    4. 步骤四:将目标类配置到Spring中

  <bean id="customerDao" class="com.itheima.demo3.CustomerDaoImpl"/>

 5. 步骤五:定义切面类

  public class MyAspectXml {
// 定义通知
public void log(){
System.out.println("记录日志...");
}
}

 6. 步骤六:在配置文件中定义切面类

  <bean id="myAspectXml" class="com.itheima.demo3.MyAspectXml"/>    

    7. 步骤七:在配置文件中完成aop的配置

 <aop:config>
<!-- 引入切面类 -->
<aop:aspect ref="myAspectXml">
<!-- 定义通知类型:切面类的方法和切入点的表达式 -->
<aop:before method="log" pointcut="execution(public * com.itheima.demo3.CustomerDaoImpl.save(..))"/>
</aop:aspect>
</aop:config>

 8. 完成测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo3 {
@Resource(name="customerDao")
private CustomerDao customerDao;
@Test
public void run1(){
customerDao.save();
customerDao.update();
customerDao.delete();
}
}

切入点的表达式
    
    1. 再配置切入点的时候,需要定义表达式,重点的格式如下:execution(public * *(..)),具体展开如下:
        * 切入点表达式的格式如下:
            * execution([修饰符] 返回值类型 包名.类名.方法名(参数))
        
        * 修饰符可以省略不写,不是必须要出现的。
        * 返回值类型是不能省略不写的,根据你的方法来编写返回值。可以使用 * 代替。
        * 包名例如:com.itheima.demo3.BookDaoImpl
            * 首先com是不能省略不写的,但是可以使用 * 代替
            * 中间的包名可以使用 * 号代替
            * 如果想省略中间的包名可以使用 ..
        
        * 类名也可以使用 * 号代替,也有类似的写法:*DaoImpl
        * 方法也可以使用 * 号代替
        * 参数如果是一个参数可以使用 * 号代替,如果想代表任意参数使用 ..

AOP的通知类型
    
    1. 前置通知
        * 在目标类的方法执行之前执行。
        * 配置文件信息:<aop:after method="before" pointcut-ref="myPointcut3"/>
        * 应用:可以对方法的参数来做校验
    
    2. 最终通知
        * 在目标类的方法执行之后执行,如果程序出现了异常,最终通知也会执行。
        * 在配置文件中编写具体的配置:<aop:after method="after" pointcut-ref="myPointcut3"/>
        * 应用:例如像释放资源
    
    3. 后置通知
        * 方法正常执行后的通知。        
        * 在配置文件中编写具体的配置:<aop:after-returning method="afterReturning" pointcut-ref="myPointcut2"/>
        * 应用:可以修改方法的返回值
    
    4. 异常抛出通知
        * 在抛出异常后通知
        * 在配置文件中编写具体的配置:<aop:after-throwing method="afterThorwing" pointcut-ref="myPointcut3"/>
        * 应用:包装异常的信息
    
    5. 环绕通知
        * 方法的执行前后执行。
        * 在配置文件中编写具体的配置:<aop:around method="around" pointcut-ref="myPointcut2"/>
        * 要注意:目标的方法默认不执行,需要使用ProceedingJoinPoint对来让目标对象的方法执行。

技术分析之:Spring框架的AOP技术(注解方式)
    
    1. 步骤一:创建JavaWEB项目,引入具体的开发的jar包
        * 先引入Spring框架开发的基本开发包
        * 再引入Spring框架的AOP的开发包
            * spring的传统AOP的开发的包
                * spring-aop-4.2.4.RELEASE.jar
                * com.springsource.org.aopalliance-1.0.0.jar
            
            * aspectJ的开发包
                * com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
                * spring-aspects-4.2.4.RELEASE.jar
    
    2. 步骤二:创建Spring的配置文件,引入具体的AOP的schema约束

      <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"> </beans>

    3. 步骤三:创建包结构,编写具体的接口和实现类
        * com.itheima.demo1
            * CustomerDao            -- 接口
            * CustomerDaoImpl        -- 实现类
    
    4. 步骤四:将目标类配置到Spring中

    <bean id="customerDao" class="com.itheima.demo1.CustomerDaoImpl"/>   

   5. 步骤五:定义切面类
        * 添加切面和通知的注解
            * @Aspect                    -- 定义切面类的注解
            
            * 通知类型(注解的参数是切入点的表达式)
                * @Before                -- 前置通知
                * @AfterReturing        -- 后置通知
                * @Around                -- 环绕通知
                * @After                -- 最终通知
                * @AfterThrowing        -- 异常抛出通知
        
        * 具体的代码如下

  @Aspect
public class MyAspectAnno {
@Before(value="execution(public void com.itheima.demo1.CustomerDaoImpl.save())")
public void log(){
System.out.println("记录日志...");
}
}  

 6. 步骤六:在配置文件中定义切面类

 <bean id="myAspectAnno" class="com.itheima.demo1.MyAspectAnno"/>    

   7. 步骤七:在配置文件中开启自动代理

<aop:aspectj-autoproxy/>
    
    8. 完成测试

 @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo1 { @Resource(name="customerDao")
private CustomerDao customerDao; @Test
public void run1(){
customerDao.save();
customerDao.update();
}
}

技术分析之通知类型
    
    1. 通知类型
        * @Before                -- 前置通知
        * @AfterReturing        -- 后置通知
        * @Around                -- 环绕通知(目标对象方法默认不执行的,需要手动执行)
        * @After                -- 最终通知
        * @AfterThrowing        -- 异常抛出通知
    
    2. 配置通用的切入点
        * 使用@Pointcut定义通用的切入点

  @Aspect
public class MyAspectAnno {
@Before(value="MyAspectAnno.fn()")
public void log(){
System.out.println("记录日志...");
}
@Pointcut(value="execution(public void com.itheima.demo1.CustomerDaoImpl.save())")
public void fn(){}
}

Spring框架的核心功能之AOP技术的更多相关文章

  1. Spring 框架的核心功能之AOP技术

    1. AOP 的概述 AOP, Aspect Oriented Programming, 面向切面编程; 通过预编译方式和运行期动态代理实现程序功能的统一维护的技术; AOP 采取横向抽取机制,取代了 ...

  2. Spring框架的核心功能之AOP概述

    1. 什么是AOP的技术? * 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程 * AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构 ...

  3. Spring框架学习(9)AOP技术理解与使用

    内容源自:AOP技术理解与使用 一.什么是AOP? aop技术是面向切面编程思想,作为OOP(面向对象编程)的延续思想添加到企业开发中,用于弥补OOP开发过程中的缺陷而提出的编程思想. AOP底层也是 ...

  4. 控制反转是Spring框架的核心。

    早在2004年,Martin Fowler就提出了“哪些方面的控制被反转了?”这个问题.他总结出是依赖对象的获得被反转了.基于这个结论,他为控制反转创造了一个更好的名字:依赖注入.许多非凡的应用(比H ...

  5. Java轻量级业务层框架Spring两大核心IOC和AOP原理

    IoC(Inversion of Control): IOC的基本概念是:不创建对象,但是描述创建它们的方式.在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务.容器负责将这些 ...

  6. Spring框架的核心模块的作用

    Spring框架由7个定义良好的模块(组件)组成,各个模块可以独立存在,也可以联合使用. (1)Spring Core:核心容器提供了Spring的基本功能.核心容器的核心功能是用Ioc容器来管理类的 ...

  7. spring两个核心IOC、AOP

    Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用.Spring是于2003 年兴起的一个轻量级的Java 开发框架,由 ...

  8. Spring框架各模块功能介绍

    一. Spring是什么? Spring由Rod johnson开发: 是一个非常活跃的开源框架: 它帮助分离项目组件(对象)之间的依赖关系: 它的主要目的是简化企业开发 二. Spring的核心概念 ...

  9. spring 框架的核心总结

    最近在学习Java语言,从而也学习了SpringFramework 这个大名鼎鼎的框架.从而做一些的记录. 题外话: 学习过几种不同的语言,后来知道所有的编程语言里所有的概念翻来覆去都是一样的事物,只 ...

随机推荐

  1. 手撕面试官系列(二):开源框架面试题Spring+SpringMVC+MyBatis

    文章首发于今日头条:https://www.toutiao.com/i6712324863006081549/ 前言 跳槽时时刻刻都在发生,但是我建议大家跳槽之前,先想清楚为什么要跳槽.切不可跟风,看 ...

  2. Serializer组件

    Serializer组件 一 .序列化器-Serializer 作用: 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串 反序列化,把客户端发送过来的数据,经过req ...

  3. 怎么理解js的原型链继承?

    前言 了解java等面向对象语言的童鞋应该知道.面向对象的三大特性就是:封装,继承,多态. 今天,我们就来聊一聊继承.但是,注意,我们现在说的是js的继承. 在js的es6语法出来之前,我们想实现js ...

  4. Luogu3214 HNOI2011 卡农 组合、DP

    传送门 火题qwq 我们需要求的是满足元素个数为\(M\).元素取值范围为\([1,2^n-1]\).元素异或和为\(0\)的集合的数量. 首先我们可以计算元素有序的方案数(即计算满足这些条件的序列的 ...

  5. UnityShader - 渲染管线

    定义: 显卡内部处理图像信号的并行处理单元,也称为渲染流水线 发生位置: CPU和GPU 渲染机理: 将图像所具备的图形信息(顶点.纹理.材质.摄像机位置等)经过一系列阶段的处理,最终转换为屏幕上的图 ...

  6. DIY一个Web框架

    一.前言 二.框架结构及实现流程 三.总结 一.前言 当我们了解了Web应用和Web框架,以及HTTP协议的原理之后,我们可以自己动手DIY一个最简单的WEB框架,以加深对Web框架的理解,并为即将学 ...

  7. 浅谈ES6中super关键字

    作用: super 关键字用于访问父对象上的函数. 语法: super([arguments]); // 访问父对象上的构造函数 super.functionOnParent([arguments]) ...

  8. 微信小程序 image组件坑

    远程图片 在真机上测试时 image组件只能显示http请求的图片, 对https 与 //xxx.xxx.xx 之类的不能显示. 可显示 'http://img.alicdn.com/i2/8323 ...

  9. vue中如何判断checkbox是否选中

    console.log(event.target.checked)     例:  

  10. vue应用难点总结

    一.父子组件生命周期 父组件create->子组件create->子组件mounted->父组件mounted 当一个钩子函数使用了异步请求时,并不会等该钩子函数中所有异步的回调都执 ...