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

  • 相关阅读:
    ADO.NET(一)数据库连接串的几种写法
    C#事件Event--猫捉老鼠
    事件
    委托
    C# .Net List<T>中Remove()、RemoveAt()、RemoveRange()、RemoveAll()的区别,List<T>删除汇总
    上传下载
    验证数据
    RSADemo2
    随机数
    二维码生成类
  • 原文地址:https://www.cnblogs.com/wangchuanfu/p/5658332.html
Copyright © 2011-2022 走看看