1、spring day01回顾
1.1 编写流程(基于xml)
1.导入jar包:4+1 --> beans/core/context/expression | commons-logging
2.编写目标类:dao和service
3.spring配置文件
IoC:
4.核心api
BeanFactory,延迟实例化bean,第一次调用getBean
ApplicationContext 一般常用,功能更强
ClassPathXmlApplicationContext 加载classpath xml文件
FileSystemXmlApplicationContext 加载指定盘符文件 , ServletContext.getRealPath()
1.2 后处理bean 对一个生效
1.3 注解
1.4 注解和xml混合使用
2、AOP
2.1 AOP介绍
2.1.1什么是AOP
1、在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
2、AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码
3、经典应用:事务管理、性能监视、安全检查、缓存 、日志等
4、Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码
AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入
2.1.2AOP实现原理
1、aop底层将采用代理机制进行实现。
2、接口 + 实现类:spring采用 jdk 的动态代理Proxy。
3、实现类:spring 采用 cglib字节码增强。
2.1.3AOP术语【掌握】
1、 target目标类:需要被代理的类。例如:UserService
2、 Joinpoint连接点:所谓连接点是指那些可能被拦截到的方法。例如:所有的方法
3、PointCut切入点:已经被增强的连接点。例如:addUser()
4、advice通知/增强,增强代码。例如:after、before
5、 Weaving织入:是指把增强advice应用到目标对象target来创建新的代理对象proxy的过程.
6、proxy代理类
7、Aspect切面:是切入点pointcut和通知advice的结合
一个线是一个特殊的面。
一个切入点和一个通知,组成成一个特殊的面。
2.2 手动方式
2.2.1JDK动态代理
JDK动态代理 对“装饰者”设计模式 简化。使用前提:必须有接口
1、目标类:接口 + 实现类
2、切面类:用于存通知 MyAspect
3、工厂类:编写工厂生成代理
4、测试
2.2.1.1 目标类
UserService.java
实现目标类
UserServiceImpl.java
2.2.1.2 切面类
MyAspect.java
2.2.1.3 工厂
MyBeanFactory.java
package com.itheima.a_proxy.a_jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyBeanFactory {
public static UserService createUserService() {
// 1 、目标类
final UserService userService = new UserServiceImpl();
// 2、切面类
final MyAspect myAspect = new MyAspect();
/**
* 3、jdk代理类:将目标类(切入点)和代理类(通知)结合-->切面
* Proxy.newProxyInstance
* 参数(1):loader 类加载器,动态代理类 运行时创建,任何类都需要将其加载到内存
* 一般情况下,当前类.class.getClassLoader()
* 目标类实例.getClass().getClassLoader()
* 参数(2):interfaces 代理类需要实现的所有接口
* 方式1:目标类实例.getClass().getInterfaces() 注意:只能获得自己的接口,不能获得父类接口
* 方式2:new Class[]{UserService.class}
* 例如:jdbc 驱动 --> DriverManager 获得接口 Connection
* 参数(3):InvocationHander 处理类,接口,必须实现类,一般采用匿名内部类
* 提供invoke 方法:代理类的每一个方法执行时,都将调用一次invoke
* 参数(3)(1):Object proxy : 代理对象
* 参数(3)(2):Method method : 代理类当前的执行方法的描述对象(反射)
* 执行方法名:method.getName()
* 执行方法:method.invoke(对象,实际参数)
* 参数(3)(3):Object[] args : 方法的实际参数
*/
UserService proxService=(UserService)Proxy.newProxyInstance(
MyBeanFactory.class.getClassLoader(),
userService.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 前执行
myAspect.before();
// 执行目标类方法
Object invoke = method.invoke(userService, args);
// 后执行
myAspect.after();
return null;
}
});
return proxService;
}
}
2.2.1.4 测试
TestJDK.java
2.2.2 CGLIB字节码增强
2.2.2.1 目标类
2.2.2.2 切面类
2.2.2.3 工厂
MyBeanFactory.java
package com.itheima.a_proxy.b_cglib;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class MyBeanFactory {
public static UserServiceImpl createUserService() {
// 1 、目标类
final UserServiceImpl userService = new UserServiceImpl();
// 2、切面类
final MyAspect myAspect = new MyAspect();
/**
* 3、代理类 ,采用cglib,底层创建目标类的子类
*/
// 3.1 核心类
Enhancer enhancer = new Enhancer();
// 3.2 确定父类
enhancer.setSuperclass(userService.getClass());
/**
* 3.3 设置回调函数,此接口等效jdk InvocationHandter接口
* 参数1,参数2,参数3:与invoke一样
* 参数4:方法的代理
*/
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
// 前方法
myAspect.before();
// 执行目标类方法
Object obj = method.invoke(userService, args);
// 执行代理类的父类,执行目标类(目标类和代理类父子关系)
// methodProxy.invokeSuper(proxy, args);
//后方法
myAspect.after();
return obj;
}
});
;
// 3.4 创建代理
UserServiceImpl proxService=(UserServiceImpl)enhancer.create();
return proxService;
}
}
2.2.2.4 测试
2.3 AOP联盟通知类型
2.4 spring编写代理:半自动
2.4.1 目标类
UserService.java
UserServiceImpl.java
2.4.2 切面类
MyAspect.java
bean.xml
2.4.3 测试
输出结果
2.5 spring aop编程:全自动【掌握】
目录结构
UserService.java
UserServiceImpl.java
MyAspect.java
bean.xml
测试
TestStringAop.java
输出结果
3、AspectJ
3.1 介绍
3.2 切入点表达式【掌握】
3.3 AspectJ 通知类型
查看源码
3.4 导入jar包
3.5 基于xml
1.目标类:接口 + 实现
2.切面类:编写多个通知,采用aspectj 通知名称任意(方法名任意)
3.aop编程,将通知应用到目标类
4.测试
目录结构
UserService.java
UserServiceImpl.java
MyAspect.java
bean.xml
3.6 基于注解
3.6.1 替换bean
3.6.2 替换aop
目录结构
UserService.java
UserServiceImpl.java
MyAspect.java
bean.xml
测试
TestAspectAnno.java
3.6.5 aop注解总结
4、JdbcTemplate
4.1.1 创建表
navicat输入以下命令:
create database ee19_spring_day02;
use ee19_spring_day02;
create table t_user(
id int primary key auto_increment,
username varchar(50),
password varchar(32)
);
insert into t_user(username,password) values('jack','1234');
insert into t_user(username,password) values('rose','5678');
4.1.2 导入jar包
目录结构
4.1.3 javabean
User.java
UserDao.java
4.2 使用api(了解)
TestApi.java
4.3 配置DBCP
bean.xml
测试
TestDBCP.java
4.4 配置C3P0
bean.xml
测试
TestC3P0.java
4.5 使用JdbcDaoSupport
bean.xml
测试
TestC3P0.java
4.5.1 源码分析
4.6 配置properties
jdbcInfo.properties
bean.xml
测试
TestC3P0.java