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) AOP是OOP (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开发依赖 asm的jar (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 Spring对AOP扩展支持

整合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/name为userService对象所有方法

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 提供切面,可以包括多个通知和多个切入点

面试题: aspect和aspectJ区别 ?

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() , 必须同时满足 pointcut1和pointcut2 切入点表达式

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

6.  Spring JdbcTemplate

学习spring 重点三--- 六章

第三章:核心技术: IoC和AOP

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

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

第六章:整合

6.1.  JdbcTemplate 快速入门

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

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

4个核心

2个日志

1个web集成

1个junit集成

1个inject

4个AOP

导入 jdbc和tx 2个jar包

导入 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 和pool的jar包

配置

6.2.3.  C3P0连接池 CombopooledDataSource 使用

导入c3p0的jar包

配置

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、 IoC和DI的概念和区别? IoC是如何实现的 ?

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

3、 BeanFactory和FactoryBean的区别 ?

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

5、 BeanPostProcessor 后处理的作用 ?

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

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

8、 传统Spring AOP 开发和配置

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

10、 advisor、advice、aspect 区别

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

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

时间: 2024-10-23 13:33:57

SpringTest2的相关文章

使用构造器装配属性

beans.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" xsi:schemaLocation="http://www.springfr

(spring-第7回【IoC基础篇】)BeanDefinition的载入与解析&amp;&amp;spring.schemas、spring.handlers的使用

报错信息:Configuration problem: Unable to locate Spring NamespaceHandler for XML schema namespace [http://www.springframework.org/schema/p], 一桩事故引发的连锁思考...开幕—— ----------------------------------------------------------------------------------------------

Spring的事务管理

事务 事务:是逻辑上一组操作,要么全都成功,要么全都失败. 事务特性(ACID) 原子性:事务不可分割 一致性:事务执行的前后,数据完整性保持一致 隔离性:一个事务执行的时候,不应该受到其他事务的打扰 持久性:一旦结束,数据就永久的保存到数据库 如果不考虑隔离性 脏读:一个事务读到另一个事务未提交数据 不可重复读:一个事务读到另一个事务已经提交数据(update)导致一个事务多次查询结果不一致 虚读:一个事务读到另一个事务已经提交数据(insert)导致一个事务多次查询结果不一致 事务的隔离级别

Spring2.5学习3.2_编码剖析@Resource注解的实现原理

首先看一下J2EE提供的@Resource注解:该注解默认安照名称进行装配,名称能够通过name属性进行指定, 假设没有指定name属性,当注解写在字段上时,默认取字段名进行依照名称查找,假设注解写在setter方法上默认取属性名进行装配. 当找不到与名称匹配的bean时才依照类型进行装配.可是须要注意的是,假设name属性一旦指定.就仅仅会依照名称进行装配. 这里我们模拟@Resource注解,便于理解注解的实现原理: 1.首先在前面模拟的容器中加入注入的方法annotationInject(

eclipse里没有j2ee

eclipse是客户端开发工具,本来就不带有j2ee的jar包,需要容器:比如tomcat来提供这个jar的.j2EE通用jar包列表:IKIKAnalyzer3.2.8.jar // 分词器ant-junit4.jar // ant junitantlr-2.7.6.jar // 没有此包,hibernate不会执行hql语句.并且会报NoClassDefFoundError: antlr/ANTLRException错误aopalliance-1.0.jar // 这个包是AOP联盟的API

AOP详解

什么是AOP AOP Aspect Oriented Programing 面向切面编程 AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视.事务管理.安全检查.缓存) Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码 AspecJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织

spring的配置模式与注解模式基础

“依赖注入”是spring的核心特征,在Web服务器(如Tomcat)加载时,它会根据Spring的配置文件中配置的bean或者是通过注解模式而扫描并装载的bean实例自动注入到ApplicationContext容器中(ApplicationContext容器管理了被注入的bean对象). 下面做两个简单测试以说明spring“依赖注入“的两种模式:配置模式与注解模式. 测试工具: 一.新建spring配置文件,放在类目录下 在“src”上右键点"new",选择"Other

spring 技术(二) ----- IOC

spring 技术 ---  控制反转(IOC)  也叫依赖注入(DI) (1)基于setter方法的注入 (2)基于构造函数的注入 (3)Bean之间的引用 1. 新建一个Java Project.名为springtest2.然后新建一个package.名为com.gxcme.springtest2. 2. 加入spring框架. 3.新建一个Interface.名为helloInterface.java. 4.新建一个class.名为helloImpl.java.继承helloInterfa

Spring In [email&#160;protected]注解给Bean命名

package soundsystem; import org.springframework.stereotype.Component; //@Component注解会告诉Spring创建这个类的实例bean(注意,启动Component注解功能需要在xml里面配置) @Component("newName") public class SgtPeppers implements CompactDisc { private String title="Pepper's Lo