zoukankan      html  css  js  c++  java
  • SpringTest2

    Spring 框架第二天 AOP切面编程 

    今天重点内容:

    1、 什么是AOP ? AOP实现原理是怎样的? AOP相关术语 

    2、 AOP底层实现 (了解) ----- JDK动态代理、 Cglib动态代理 

    3、 传统Spring AOP 编程 (了解实现,掌握使用 )

    4、 基于AspectJ 框架,实现spring2.0之后 AOP 编程(重点)

    5、 Spring JdbcTemplate 模板工具类 使用 (ORM 解决方案 )--- 类似Apache DbUtils

    1.  AOP面向切面编程概述

    1.1.  什么是AOP 

    l AOP Aspect Oriented Programing 面向切面编程 

    1) 一种程序设计思想 

    2) 

    3) AOPOOP Object Oriented Programing )延伸 

    l 思想:AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)

    AOP底层就是代理的增强 ! 

    l 面试题:在项目哪些功能使用AOP ? --- AOP使用场景

    1、性能监视 (方法运行时间)

    2、事务管理 

    3、安全检查 (权限 )

    4、缓存优化 (第一次访问,查询数据,放入缓存, 第二次以后访问 从缓存返回 )

    5、记录日志 

    l 学习AOP 分为两个部分 

    1、 学习传统Spring AOP编程 (Spring1.2年代 )

    2、 学习AspectJ 框架的AOP编程 (Spring2.0以后年代 )

    1.2.  AOP开发术语 

    切面由切入点和通知组成! 

    2.  AOP的底层实现(了解)

    2.1.  JDK 动态代理机制

    1、必须针对接口进行代理 

    2、生成代理对象,通过Proxy类 

    进行代理 ,传入目标对象类加载器、 目标对象接口 、 处理类 

    3、自己实现InvocationHandler 接口 

    对目标对象方法调用时,都会执行invoke方法,起到拦截作用 

    第一步: 编写业务接口和实现类

    第二步: 编写传统调用,编写基于代理调用 

    // 生成代理工具类

    public class JdkProxyFactory implements InvocationHandler{

    // 目标对象

    private Object target;

    public JdkProxyFactory(Object target) {

    this.target = target;

    }

    // 创建代理对象

    public Object createJdkProxy(){

    return Proxy.newProxyInstance(

    target.getClass().getClassLoader(), 

    target.getClass().getInterfaces(), 

    this);

    }

    @Override

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    // 记录日志

    System.out.println("日志记录:" + method.getName() + "执行了...");

    return method.invoke(target, args);

    }

    }

    第三步: 测试代码

    2.2.  Cglib动态代理机制 

    JDK只能对接口进行代理,如果目标对象没有接口,无法使用JDK动态代理 ---- 使用cglib 

    什么是cglib ? 

    CGLIB(Code Generation Library)是一个开源项目!是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。

    Cglib可以对接口或者类进行代理 !

    使用Spring最新版本开发,无需单独下载cglib (spring core 已经集成cglib )

    Cglib开发依赖 asmjar spring core 已经集成 asm 

    1、 编写目标业务类 

    2、编写Cglib 生成代理工厂类 

    // 生成cglib代理工厂

    public class CglibProxyFactory implements MethodInterceptor {

    // 目标对象

    private Object target;

    public CglibProxyFactory(Object target) {

    this.target = target;

    }

    // 生成代理对象方法

    public Object createCglibProxy() {

    // 通过Enhancer 生成代理

    Enhancer enhancer = new Enhancer();

    // 设置超类

    // 生成UserDAO的子类

    enhancer.setSuperclass(target.getClass());

    // 设置回调处理类

    enhancer.setCallback(this);

    // 生成代理返回

    return enhancer.create();

    }

    @Override

    /**

     * proxy 代理对象

     * method 方法反射对象

     * args 参数

     * methodProxy 方法的代理对象,用于执行父类的方法 

     */

    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

    System.out.println("cglib 日志: 调用了" + method.getName() + "方法...");

    // return method.invoke(target, args);

    return methodProxy.invokeSuper(proxy, args);// 调用真实对象方法

    }

    }

    3、编写测试类 

    小结: 

    Spring AOP 就是基于JDKProxy 和 CglibProxy 

    1、如果目标对象有接口,优先使用JDK Proxy

    2、如果目标对象没有接口, 使用CglibProxy 

    3.  传统Spring AOP 切面编程 

    传统 : Spring1.2 开始支持AOP编程 (这种编程,现在自己写的很少,但是我们会用到 )

    Spring AOP编程,必须学习切入点和通知 

    1) 切入点,通过配置完成的

    2) 通知,通过编程完成的 

    3.1.  传统AOP编程,通知类型(5)

    不同Advice 执行增强代码的时间点不同 ! 

    3.2.  编写一个Advice 

    1、 导入jar包 

    传统Spring AOP开发 

    • com.springsource.org.aopalliance-1.0.0.jar AOP联盟定义接口规范
    • spring-aop-3.2.0.RELEASE.jar SpringAOP扩展支持 

    整合AspectJ AOP开发

    • com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar 第三方AspectJ 
    • spring-aspects-3.2.0.RELEASE.jar Spring AspectJ 扩展支持 

    2、 编写Advice 实现 MethodInterceptor 环绕增强 

    3.3.  AspectJ 切入点语法 

    为什么要学习AspectJ切入点语法? 

    传统AOP切入点 ,使用正则表达式语法,现在基本上不去用 

    Spring没有支持所有AspectJ语法,所以我们学习Spring AOP 只能spring文档 !

    AspectJ切入点,是通过函数进行配置 

    l execution 执行

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

    execution(* *(..))  第一个任意返回类型 , 第二个任意方法名 , .. 任意参数 

    execution(* cn.itcast.service.UserService.*(..)) 匹配UserService所有方法 

    execution(* cn.itcast.service.UserService+.*(..)) 匹配UserService子类所有方法 

    execution(* cn.itcast.service..*.*(..)) 第一个.. 任意子包 *.*任何类的任何方法 

    l within 根据包匹配

    n 语法:within(包名..*) 

    within(cn.itcast.service..*) 拦截service下所有类的方法 

    l this根据目标类型匹配

    n 语法:this(类名

    this(cn.itcast.service.UserService) 拦截 UserService所有方法 (包括代理对象)

    l target 根据目标类型匹配

    n 语法 :target(类名)

    target(cn.itcast.service.UserService) 拦截UserService所有方法 (不包括代理对象 )

    l args 根据参数匹配

    args(java.lang.String) 拦截所有参数为String类的方法 

    l bean 根据bean name匹配 

    bean(userService) 拦截bean id/nameuserService对象所有方法 

    3.4.  配置传统Spring AOP切面

    1、 引入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"

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

     

    </beans>

    2、 配置切面 

    3、编写测试

    图解:

    注意: 需要对有接口实现类直接代理,不对接口代理 !

    4.  AspectJ AOP切面编程(XML配置)

    Spring1.2 开始支持AOP编程,主要代理对象创建通过ProxyFactoryBean构造 !

    后来人们发现spring1.2 AOP开发太麻烦了,spring2.0 引入对AspectJ(第三方AOP框架)支持,AOP开发就被简化了。 

    4.1.  AspectJ支持通知类型 (6)

    相比传统AOP编程,多了一个After通知(最终通知, 效果finally 

    4.2.  Before前置通知使用 

    分析前置通知应用场景: 权限控制、 记录访问日志 

    第一步: 编写Advice 

    第二步: 配置切入点和切面 

    面试题: advisor和 aspect的区别 ? 

    Advisor是传统Spring AOP 切面,只能有一个通知和一个切入点

    Aspect AspectJ 提供切面,可以包括多个通知和多个切入点

    面试题: aspectaspectJ区别 ?

    aspect 切面, 由切入点和通知组成

    aspectJ 框架,进行AOP开发 

    ===================== 扩展 struts2 拦截器机制是AOP思想吗? 

    1、 访问Action 进行代理 ActionProxy 

    2、 提供Interceptor 类似Advice 增强 ,通过配置使不同Action访问前执行不同拦截器

    4.3.  AfterReturing 后置通知使用

    在目标类的方法运行之后,进行代码增强 

    特性:操作目标方法返回值  

    使用AspectJ 框架开发,可以将多个增强的方法,写在同一个类里面 !

    第一步: 编写增强方法

    第二步: 配置applicationContext.xml 

    4.4.  Around 环绕通知使用 

    在目标类方法 执行前和执行后,都可以增强 

    场景: 1) 运行方法时间监控 2) 事务管理 3) 权限控制 4) 缓存 5) 日志 

    第一步: 编写Advice增强方法 

    第二步: 配置切入点和切面 

    4.5.  AfterThrowing 抛出通知使用 

    在目标发生异常时,执行增强代码 

    场景: 目标方法异常,日志记录异常,将异常信息发送邮件给管理员 

    第一步: 编写抛出增强方法 

    第二步: 配置切入点和切面 

    当发生异常时, 目标方法后置通知不会执行的!!

    4.6.  After最终通知使用

    无论目标方法是否出现异常,都将执行增强代码 

    场景: 释放资源 

    try {

      开启事务…

      执行代码

    } catch {

       事务回滚

    } finally {

       事务提交

    }

    第一步: 编写增强方法 

    第二步: 配置切入点和切面 

    小结: Around环绕通知什么都可以 

    try{

    前置通知… 

    执行目标方法

    后置通知…

    }catch {

    异常通知…

    }finally {

    最终通知…

    }

    5.  AspectJ AOP 切面编程 (注解配置 )

    新建 spring3_day3_annotation web 项目, 导入spring AOP开发jar包 

    5.1.  编写目标业务类 

    配置applicationContext.xml bean的扫描 

    5.2.  编写Advice增强 

    配置applicationContext.xml 

    使用注解修饰Advice类 

    @Aspect 这是一个切面 

    @Before 前置通知

    @AfterReturning 后置通知

    @Around 环绕通知

    @AfterThrowing 抛出通知 

    @After最终通知 

    @Pointcut 切入点 

    小结: 

    1、 注册Bean  <context:component-scan> @Service@Controller、 @Repository @Component 

    2、 声明具有增强方法类是一个切面 @Aspect 

    3、 在对应方法上,声明各种通知 @Before @AfterReturning @Around @AfterThrowing @After 

    4、 根据切面注解自动生成代理 <aop:aspectj-autoproxy  />

    5.3.  使用@Pointcut 定义切入点 

    将公共切入点表达式,抽取出来,便于后期维护 

    Spring规定,将@Pointcut注解加到 私有、无返回值、无参数的方法上 (该方法的名字 就是切入点的名字 !)

    如果引用切入点,类似方法调用 

    能否在一个通知上, 应用多个切入点 可以 && 或者 || 引入多个 

    pointcut1() && pointcut2() , 必须同时满足 pointcut1pointcut2 切入点表达式 

    pointcut1()||pointcut2() 只需要满足 pointcut1 或者 pointcut2 当中一个切入点表达式 

    6.  Spring JdbcTemplate 

     学习spring 重点三--- 六章 

    第三章:核心技术: IoCAOP 

    第四章:数据访问: (JDBC数据访问 JdbcTemplate 、 事务管理 、 整合ORM框架 )

    第五章:Web应用 :SpringMVC --- 后续课程 

    第六章:整合 

    6.1.  JdbcTemplate 快速入门 

    JdbcTemplate 用来简化JDBC 编程开发,使用效果类似 DbUtils 框架 

    第一步: 新建web项目 spring3_day2_jdbctemplate ,导入jar包 

    4个核心

    2个日志

    1web集成

    1junit集成

    1inject 

    4AOP 

    导入 jdbctx 2jar包 

    导入 oracle驱动 

    第二步: 编写无配置文件Jdbc程序 

    -- Create the user 

    create user SH1026

      identified by ""

      default tablespace SYSTEM

      temporary tablespace TEMP

      profile DEFAULT;

    -- Grant/Revoke role privileges 

    grant connect to SH1026;

    grant resource to SH1026;

    -- Grant/Revoke system privileges 

    grant unlimited tablespace to SH1026;

    6.2.  使用spring配置管理JdbcTemplate 

    applicationContext.xml 配置数据库连接池和JdbcTemplate 

    6.2.1.  DrvierManagerDataSource 配置

    测试

    6.2.2.  DBCP 连接池BasicDataSource 配置 

    导入 dbcp pooljar包 

    配置 

    6.2.3.  C3P0连接池 CombopooledDataSource 使用

    导入c3p0jar包 

    配置

    6.2.4.  JNDI数据库配置使用 

    什么是JNDI ? 

    JNDI(Java Naming and Directory Interface,Java命名和目录接口) 

    JNDI容器进行配置,将对象交给容器创建和管理,为对象进行命名 ,在JNDI容器其它程序通过名字去访问这个对象。 

    第一步: 在tomcat配置数据库连接池 

    需要在<Context>元素下配置 <Resouce> 元素 

    配置位置 : server.xml context.xml (所有项目生效)、 项目目录 WebRoot/META-INF (只对当前项目有效 ) 

    在项目WebRoot/META-INF 新建context.xml  

    将数据库驱动包,复制tomcat/lib下 

    第二步: spring访问 配置JNDI 

    配置applicationContext.xml 

    编写Servlet ,从Spring获取对象 

    6.3.  外部属性文件的配置使用 

    什么是外部属性文件? 

    属性文件 --- properties文件 

    XML中很多内容,格式比properties 复杂, 将经常需要改动属性数据,配置properties文件, 便于后期维护! 

    applicationContext.xml 引入属性文件,通过${} 引入属性值 

    6.4.  编写DAO程序,实现数据表CRUD操作 

    6.4.1.  建立数据表,编写实体类

    建立customers数据表 

    -- Create table

    create table customers

    (

      id   number,

      name varchar2(50),

      city varchar2(100),

      age  number

    )

    ;

    -- Create/Recreate primary, unique and foreign key constraints 

    alter table customers

      add constraint customers_pk primary key (ID);

    实体类

    6.4.2.  在DAO中注入JdbcTemplate 

    配置 

    6.4.3.  通过update方法,实现增加、修改、删除 

    JdbcTemplate提供 

    6.4.4.  通过queryXxx方法实现查询 

    l 返回简单类型数据

    返回int : queryForInt

    返回long: queryForLong

    返回String : queryForObject(sql, requiredType, args ) requiredType就是返回类型 

    l 返回复杂类型数据: 

    需要使用RowMapper对象 

    什么是RowMapper ?  将每行数据封装为Customer对象 

    问题: 如果表中列非常多, 自定义RowMapper 非常复杂 

    类属性名和表列名,代码能否优化 !

    Spring JdbcTemplate 提供ParameterizedBeanPropertyRowMapper ,自动完成同名列和属性 自动对应封装 !

    今天总结: 

    1、 IoCDI的概念和区别? IoC是如何实现的 ?

    2、 什么AOP? 如何实现的? 在项目哪些功能中使用到AOP 

    3、 BeanFactoryFactoryBean的区别 ?

    4、 singletonprototype的区别 能否写出单例设计模式代码实现 ?

    5、 BeanPostProcessor 后处理的作用 ?

    6、 如何用xml和注解 定义Bean? 如何完成属性注入 ? 

    7、 Spring AOP 使用什么技术实现的 ? 底层技术 JDKCglib动态代理 

    8、 传统Spring AOP 开发和配置 

    9、 重点掌握 AspectJ AOP 开发和配置 (XML和注解,重点掌握一种 )

    10、 advisoradviceaspect 区别

    11、 SpringAOP 应用: 运行时间、 权限控制、 缓存、事务管理  … 

    12、 数据源配置 JNDI 和 C3p0 重点 

  • 相关阅读:
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & ManacherK
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher J
    [kuangbin带你飞]专题十六 KMP & 扩展KMP & Manacher I
    pat 1065 A+B and C (64bit)(20 分)(大数, Java)
    pat 1069 The Black Hole of Numbers(20 分)
    pat 1077 Kuchiguse(20 分) (字典树)
    pat 1084 Broken Keyboard(20 分)
    pat 1092 To Buy or Not to Buy(20 分)
    pat 1046 Shortest Distance(20 分) (线段树)
    pat 1042 Shuffling Machine(20 分)
  • 原文地址:https://www.cnblogs.com/wangchuanfu/p/5658332.html
Copyright © 2011-2022 走看看