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是一种用于快速创建动态网页的技术,他通过在后台与服务器进行少量的数据交换,可以实现网页的异步更新,不需要像传统网页那样重新加载页面也可以做到对网页的某部分作出更新,现在这项技 ...
随机推荐
- iOS音频开发系列-概述篇
概述 iOS中对于音频的处理,苹果提供了两个库. AVFoundation AudioToolbox 在iOS系统中apple对上述的流程进行了封装并提供了不同层次的接口
- http协议 头部字段 referrer
学习笔记,非原创,抄自:https://www.cnblogs.com/amyzhu/p/9716493.html:https://blog.csdn.net/java_zhangshuai/arti ...
- Java获取文件Content-Type(Mime-Type)
Java获取文件Content-Type(Mime-Type) 刚好工作中要用到,所以总结一下.推荐使用第一种和第三种,实在不行,也可以去把http://tool.oschina.net/common ...
- vue中获取节点.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- CF822F Madness
题意:给你一棵边权都为1的树,要求选择互不相交的若干条路径,这些路径包含有所有点. 在每一条路径上选择一条边,放置一个动点,设置一个方向,它开始在该路径上来回运动,速度为1.每个点上都有一个停表,当有 ...
- Java怎样实现解析身份证号
身份证号解析,demo /** * 身份证号解析demo * */ public class TestArea { public static void main(String[] args) { S ...
- 树莓派3B+ 人脸识别、摄像头安装和使用
最近在学校里折腾树莓派上的人脸识别,折腾了很久才能用 在此记录下使用的过程和遇到的困难 过程基于超有趣!手把手教你使用树莓派实现实时人脸检测完成的.其中前面opencv的安装是文章中的Raspbian ...
- kaptcha 实现验证码
依赖 <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha< ...
- type元类创建类的方法
一.代码 class_name='car' dict_name={} bases=(object,) class_body=''' def __init__(self,name): self.name ...
- chattr和lsattr命令,不能被删除、改名、设定链接关系,同时不能写入或新增内容
chattr和lsattr命令详解 chattr命令的作用很大,其中一些功能是由Linux内核版本来支持的,如果Linux内核版本低于2.2,那么许多功能不能实现.同样-D检查压缩文件中的错误的功能, ...