04_Spring AOP两种代理方法
什么是AOP?
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
应用场合:事务管理、性能监视、安全检查、缓存 、日志等。
Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码。
AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码。
纵向继承:

横向抽取:

AOP底层将采用代理机制实现
1.接口 + 实现类 :spring采用 jdk 的动态代理Proxy。
2.实现类:spring 采用 cglib字节码增强代理。
代码实现:在增删改方法之前,增加事务处理(开启事物,提交事物),前提不修改当前类。
userService.java
public interface userService {
void save();
void delete();
void update();
void find();
}
userServiceImpl.java
@Component("userService")
public class userServiceImpl implements userService{
//增强
public void save() {
System.out.println("保存用户");
}
public void delete() {
//
System.out.println("删除用户");
//
}
public void update() {
System.out.println("修改用户");
}
public void find() {
System.out.println("查找用户");
}
}
1)JDK 动态代理
jdk动态代理实现主要靠Proxy类和InvocationHandler接口来实现。
userServiceProxyFactory.java
public class userServiceProxyFactory implements InvocationHandler{
//代理对象
private userService us;
public userServiceProxyFactory(userService us){
super();
this.us=us;
}
//返回代的对象
//参数1,类加载器 参数2,代理类的接口 参数3.实现增强的代码(对原方法增强的一个方法)
public userService getUserServiceProxy(){
return (UserService)Proxy.newProxyInstance(userServiceProxyFactory.class.getClassLoader(),
UuerServiceImpl.class.getInterfaces(),this);
}
@Override
//参数1,代理对象 参数2,原代理对象的方法 参数3,代理方法的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//增强
System.out.println("开启事务"); //前置通知
Object invoke = method.invoke(us, args); //调用原方法(切入点) + (通知) = 切面
System.out.println("提交事务"); //后置通知
return invoke;
}
}
测试代码:
public class Mytest {
@Test//动态代理
public void test(){
userService us = new userServiceImpl();
userServiceProxyFactory factory = new userServiceProxyFactory(us);
userService userServiceProxy = factory.getUserServiceProxy();//返回代理后的对象
//未使用jdk动态代理
us.save();
System.out.println("--------------------------");
//使用动态代理对象
userServiceProxy.save();
}
}
2)CGLIB代理
public class UserServiceProxyFactory2 {
//代理对象
/*private UserService us;
public UserServiceProxyFactory2(UserService us){
super();
this.us=us;
}*/
//返回代理对象
public UserService getUserServiceProxy(){
Enhancer en = new Enhancer(); //帮我们生成代理对象
en.setSuperclass(UserServiceImpl.class);
en.setCallback(new MethodInterceptor() {
@Override
//参数1,目标对象 参数2,目标对象的方法 参数3,方法中参数 参数4 代理方法
public Object intercept(Object proxyObj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("开启事务");
//目标方法调用
//Ojbect invoke = method.invoke(us, args)
Object invokeSuper = methodProxy.invokeSuper(proxyObj, args);
System.out.println("提交事务");
return invokeSuper;
}
});
UserService us = (UserService) en.create(); //创建代理对象
return us;
}
}
测试代码
public class Mytest {
@Test
public void test2(){
UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();
UserService userServiceProxy = factory.getUserServiceProxy();
UserServiceProxy.save();
}
}
04_Spring AOP两种代理方法的更多相关文章
- 死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
- spring AOP的两种代理
本篇记录下spring AOP的两种代理,为下一篇AOP实现做下铺垫. 1.JDK动态代理 2.cglib代理 1.如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP2.如果目标对象 ...
- JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解
在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...
- Spring两种代理区别
Spring的两种代理JDK和CGLIB的区别浅谈: Java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用invokeHandler类来处理: 而cglib动态代理是利用a ...
- Spring的两种代理方式:JDK动态代理和CGLIB动态代理
代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对 ...
- Spring-Aop的两种代理方式
Spring-Aop两种代理方式: 1.JDK动态代理:用于目标类实现了接口: 2.Cglib动态代理:用于目标类没有实现接口: spring会依据目标类是否实现接口来选择使用哪种代理方式(目标类:相 ...
- angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用
今天我们要讲的是ng2的路由系统. 例子
- git两种合并方法 比较merge和rebase
18:01 2015/11/18git两种合并方法 比较merge和rebase其实很简单,就是合并后每个commit提交的id记录的顺序而已注意:重要的是如果公司用了grrit,grrit不允许用m ...
- 两种Ajax方法
两种Ajax方法 Ajax是一种用于快速创建动态网页的技术,他通过在后台与服务器进行少量的数据交换,可以实现网页的异步更新,不需要像传统网页那样重新加载页面也可以做到对网页的某部分作出更新,现在这项技 ...
随机推荐
- netty 文件传输
FileServer package com.zhaowb.netty.ch13_1; import io.netty.bootstrap.ServerBootstrap; import io.net ...
- 360自动抢票还不够,几行js代码设置无人值守
360就是牛逼哄哄的...... 但是最近在使用360浏览器抢票的时候还是发现了一些体验不好的地方,比如搞着搞着就退出了登录,有时候能帮你自动登录进去,但是自动登录之后又不会帮你自动开始抢.然后验证码 ...
- 数据库MySQL--分组查询
事例使用文件:https://files.cnblogs.com/files/Vera-y/myemployees.zip 分组数据:group by 子句 分组查询语法: select 分组函数,列 ...
- jpa 踩坑 SQLGrammarException
SQLGrammarException could not execute query cause by not found column id ,, id指的是,返回的结果没有Id 封装结果集出错 ...
- buff/cache内存占用过多
通过free -m 查看到 buff/cache的值比较大,导致可使用的内存有120M左右了 通过下面的命令,清除缓存 echo 1 > /proc/sys/vm/drop_caches ech ...
- 单独编译和使用webrtc音频降噪模块(附完整源码+测试音频文件)
单独编译和使用webrtc音频增益模块(附完整源码+测试音频文件) 单独编译和使用webrtc音频回声消除模块(附完整源码+测试音频文件) webrtc的音频处理模块分为降噪ns,回音消除aec,回声 ...
- day25 模块,sys, logging, json, pickle
Python之路,Day13 = Python基础13 sys模块 sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sy ...
- thinkphp 模板继承
模板继承是一项更加灵活的模板布局方式,模板继承不同于模板布局,甚至来说,应该在模板布局的上层.模板继承其实并不难理解,就好比类的继承一样,模板也可以定义一个基础模板(或者是布局),并且其中定义相关的区 ...
- C++调用JS,JS调用C++
JS调用C++,通过设置DIID_HTMLDocumentEvents事件,来捕获HTMLWINDOW上的事件,再通过事件对象的get_srcElement得到事件源,从而得到指定元素对象,从而获取元 ...
- hdu多校第四场 1003 (hdu6616) Divide the Stones 机智题
题意: 给你重量分别为1到n的n个石头,让你分成重量相等,数量也相等的k组,保证k是n的约数.问你能不能分配,如果能,输出具体的分配方案. 题解: 首先,如果1到n之和不能整除k,那么一定不能如题意分 ...