1.AOP
1.1 AOP案例引入
1.1.1 数据库事务说明
案例分析:
1. userMapper.insert(User对象)
2. deptMapper.insert(dept对象)
说明: 由于业务需求 要求方法要么同时入库,要么同时回滚.所以必须通过事务进行控制.
1.2 Spring实现事务控制(demo)
1.2.1 代码结构如下
1.2.2 编辑UserMapper/UserMapperImpl
1).编辑UserMapper
2).编辑UserMapperImpl
1.2.3 编辑UserService/UserServiceImpl
1).编辑UserService
2)编辑UserServiceImpl
1.2.4 编辑配置类
1.2.5 编辑测试类
1.3 代码问题分析
解决方案: 采用代理模式进行编辑.
1.4 代理模式
1.4.1 生活中代理案例
房屋中介代理模式:
1.房东: 自己手里有房子 需要出租换钱
2.中介机构 1.本职工作 带客户看房/出租房屋 2.收取中介费(服务费)
3.租客: 满足自身需求 租房子
代码思维建模:
1.暴露一个公共的接口(租房子)
2.客户与中介机构进行沟通,中介看起来和房东功能一致.
(代理看起来就是真实的对象)
3.完成用户额外的操作(收取中介费)
1.4.2 代理模式
1).组成部分
1.要求代理者实现与被代理者相同的接口
2.在代理方法中实现功能的扩展
3.用户调用代理对象完成功能(用户认为代理就是目标对象)
2).调用流程
1.5 静态代理
1.5.1 通过代理模式实现事务控制
角色划分:
1.目标对象target UserServiceImpl类
2.目标方法 method addUser()方法
3.代理: 实现事务控制.
4.代理对象与目标对象实现相同的接口.
1.5.2 修改目标对象名称
1.5.3 编辑代理类
@Service("userService") public class StaticProxy implements UserService {
<span class="token comment">//要求引入目标对象</span> <span class="token annotation punctuation">@Autowired</span> <span class="token comment">//ByType byName</span> <span class="token comment">//@Qualifier("target")</span> <span class="token keyword">private</span> UserService target<span class="token punctuation">;</span> <span class="token comment">//目的: 对原有方法进行扩展</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addUser</span><span class="token punctuation">(</span>User user<span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> <span class="token keyword">try</span> <span class="token punctuation">{<!-- --></span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"事务开始"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> target<span class="token punctuation">.</span><span class="token function">addUser</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"事务结束"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"事务回滚"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
1.5.4 编辑测试类
@Test
public void testStaticProxy(){
ApplicationContext context =
new AnnotationConfigApplicationContext(SpringConfig.class);
UserService userService = (UserService) context.getBean("userService");
User user = new User();
user.setId(10001);
user.setName("测试代理机制");
//执行用户调用
userService.addUser(user);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
1.5 静态代理弊端
1).静态代理只针对于某个接口 不能实现所有接口的代理 实用性较差
2).静态代理中所有的方法,都需要手动的添加事务开始/事务提交代码 代码冗余 不够简洁.
1.6 动态代理机制
1.6.1 动态代理分类(考题)
1.JDK代理:
要求: 要求目标对象必须实现接口
代理要求: 代理对象也必须实现目标对象的接口
目标对象/代理关系: 目标对象与代理对象兄弟关系.
2.CGlib代理
要求: 不管目标对象是否有接口,都可以为其创建代理对象
代理要求: 要求代理对象必须继承目标对象
目标对象/代理关系: 目标对象与代理对象是父子关系
1.6.2 编辑JDK动态代理
官网API:
背会知识点:
1.关于匿名内部类用法说明: 匿名内部类引用外部参数 要求参数必须final修饰
2. 该方法标识 当代理对象执行时,"回调"该方法.
java public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {}
3. 目标方法执行
java result = method.invoke(target,args);
package com.jt.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//能否利用一个工厂动态为目标对象创建代理
public class JDKProxyFactory {
<span class="token comment">//要求用户传递目标对象</span>
<span class="token comment">//关于匿名内部类用法说明: 匿名内部类引用外部参数 要求参数必须final修饰</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> Object <span class="token function">getProxy</span><span class="token punctuation">(</span><span class="token keyword">final</span> Object target<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
<span class="token comment">//1.调用java API实现动态代理</span>
<span class="token comment">/**
* 参数分析: 3个参数
* 1.ClassLoader loader, 类加载器(获取目标对象的Class)
* 2.类<?>[] interfaces, JDK代理要求 必须有接口
* java中可以多实现
* 3.InvocationHandler h 对目标方法进行扩展
*/</span>
<span class="token comment">//1.获取类加载器</span>
ClassLoader classLoader <span class="token operator">=</span> target<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getClassLoader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//2.获取接口数组</span>
Class<span class="token punctuation">[</span><span class="token punctuation">]</span> interfaces <span class="token operator">=</span> target<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getInterfaces</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//3.通过动态代理创建对象</span>
Object proxy <span class="token operator">=</span> Proxy<span class="token punctuation">.</span><span class="token function">newProxyInstance</span><span class="token punctuation">(</span>classLoader<span class="token punctuation">,</span> interfaces<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">InvocationHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token comment">//invoke方法: 代理对象调用方法时invoke执行,扩展方法的编辑位置</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> Object <span class="token function">invoke</span><span class="token punctuation">(</span>Object proxy<span class="token punctuation">,</span> Method method<span class="token punctuation">,</span> Object<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token keyword">throws</span> Throwable <span class="token punctuation">{<!-- --></span>
<span class="token comment">// result 标识目标方法执行的返回值</span>
Object result <span class="token operator">=</span> null<span class="token punctuation">;</span>
<span class="token keyword">try</span> <span class="token punctuation">{<!-- --></span>
<span class="token comment">//添加事务的控制</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"事务开始"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//执行目标方法</span>
<span class="token comment">// target真实的目标对象,method方法对象,args方法参数</span>
result <span class="token operator">=</span> method<span class="token punctuation">.</span><span class="token function">invoke</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"事务提交"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"事务回滚"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">return</span> result<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> proxy<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
1.6.3 JDK动态代理执行过程
1.7 动态代理优势
将公共的部分写到动态代理中,之后其他的业务类调用即可
1.7.1 编辑DeptService/DeptServiceImpl
1).编辑DeptService
2).编辑DeptServiceImpl
1.7.2 编辑测试类
public class TestDept {
<span class="token annotation punctuation">@Test</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">testTx</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> <span class="token comment">//1.获取目标对象</span> ApplicationContext context <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AnnotationConfigApplicationContext</span><span class="token punctuation">(</span>SpringConfig<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span> DeptService target <span class="token operator">=</span> <span class="token punctuation">(</span>DeptService<span class="token punctuation">)</span> context<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token string">"deptService"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//2.获取代理对象</span> DeptService deptService <span class="token operator">=</span> <span class="token punctuation">(</span>DeptService<span class="token punctuation">)</span> JDKProxyFactory<span class="token punctuation">.</span><span class="token function">getProxy</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//通过代理对象 调用方法 扩展了方法!!!!!</span> deptService<span class="token punctuation">.</span><span class="token function">addDept</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//invoke</span> <span class="token punctuation">}</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
1.8 动态代理实现方案(二)
1.8.1 业务需求
要求对Service层的方法记录其执行的时间!!! 通过执行时间的长短 进行针对性的优化!!!
要求: service中 有 addUser方法/deleteUser方法.
要求代码结构扩展性好,耦合性低.
做完1000块!!!
1.8.2 编辑UserService/UserServiceImpl
1).编辑UserService
public interface UserService {
<span class="token keyword">void</span> <span class="token function">addUser</span><span class="token punctuation">(</span>User user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">void</span> <span class="token function">deleteUser</span><span class="token punctuation">(</span>User user<span class="token punctuation">)</span><span class="token punctuation">;</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
2).编辑UserServiceImpl
@Service("target") public class UserServiceImpl implements UserService{
<span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"新增用户"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">deleteUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"删除用户"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
1.8.3 编辑代理工厂
package com.jt.proxy;
import javax.annotation.PostConstruct;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxyFactory {
<span class="token comment">//编辑静态方法获取代理对象</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> Object <span class="token function">getProxy</span><span class="token punctuation">(</span><span class="token keyword">final</span> Object target<span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span>
<span class="token comment">//3个参数 1.类加载器 2.对象的接口</span>
ClassLoader classLoader <span class="token operator">=</span> target<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getClassLoader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
Class<span class="token punctuation">[</span><span class="token punctuation">]</span> interfaces <span class="token operator">=</span> target<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getInterfaces</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
Object proxy <span class="token operator">=</span> Proxy<span class="token punctuation">.</span><span class="token function">newProxyInstance</span><span class="token punctuation">(</span>classLoader<span class="token punctuation">,</span> interfaces<span class="token punctuation">,</span>
<span class="token keyword">new</span> <span class="token class-name">InvocationHandler</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{<!-- --></span>
<span class="token comment">//代理对象执行目标方法时执行</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> Object <span class="token function">invoke</span><span class="token punctuation">(</span>Object proxy<span class="token punctuation">,</span> Method method<span class="token punctuation">,</span> Object<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token keyword">throws</span> Throwable <span class="token punctuation">{<!-- --></span>
<span class="token comment">//让用户执行目标方法</span>
Long startTime <span class="token operator">=</span> System<span class="token punctuation">.</span><span class="token function">currentTimeMillis</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//开始时间</span>
<span class="token comment">//执行目标方法 获取返回值 可能为null</span>
Object result <span class="token operator">=</span> method<span class="token punctuation">.</span><span class="token function">invoke</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span>
Long endTime <span class="token operator">=</span> System<span class="token punctuation">.</span><span class="token function">currentTimeMillis</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//结束时间</span>
<span class="token comment">//根据项目经理要求 给程序预留bug 后期维护时删除 不友好</span>
Thread<span class="token punctuation">.</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"程序执行:"</span><span class="token operator">+</span><span class="token punctuation">(</span>endTime<span class="token operator">-</span>startTime<span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">"毫秒"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//将返回值传递给调用者</span>
<span class="token keyword">return</span> result<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">;</span>
<span class="token keyword">return</span> proxy<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
1.8.4 编辑测试案例
public class TestSpring {
<span class="token annotation punctuation">@Test</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test01</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{<!-- --></span> ApplicationContext context <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AnnotationConfigApplicationContext</span><span class="token punctuation">(</span>SpringConfig<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//1.获取目标对象</span> UserService target <span class="token operator">=</span> <span class="token punctuation">(</span>UserService<span class="token punctuation">)</span> context<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token string">"target"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//2.获取代理对象</span> UserService proxy <span class="token operator">=</span> <span class="token punctuation">(</span>UserService<span class="token punctuation">)</span> JDKProxyFactory<span class="token punctuation">.</span><span class="token function">getProxy</span><span class="token punctuation">(</span>target<span class="token punctuation">)</span><span class="token punctuation">;</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>proxy<span class="token punctuation">.</span><span class="token function">getClass</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//3.调用业务方法</span> proxy<span class="token punctuation">.</span><span class="token function">addUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
1.9 业务案例3
要求进行日志控制 1000块
要求方法执行时,获取方法名,及所在类的名称 进行控制台输出. 以及方法的执行时间
作业
1).熟练编辑3层代码结构 5遍
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、pandas是什么?
示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
二、使用步骤
1.引入库
代码如下(示例):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
2.读入数据
代码如下(示例):
data = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())
该处使用的url网络请求的数据。
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。