Spring AOP基础知识
Spring AOP使用动态代理技术在运行期织入增强的代码,两种代理机制包括:一是基于JDK的动态代理,另一种是基于CGLib的动态代理。之所以需要两种代理机制,很大程度上是因为JDK本身只提供接口的代理,而不支持类的代理。
package com.yyq.proxy;
public interface ForumService {
void removeTopic(int topicId);
void removeForum(int forumId);
}
ForumServiceImpl:实现类
package com.yyq.proxy; public class ForumServiceImpl implements ForumService {
@Override
public void removeTopic(int topicId) {
PerformanceMonitor.begin("com.yyq.proxy.ForumServiceImpl.removeTopic");
System.out.println("模拟删除Topic记录:" + topicId);
try {
Thread.currentThread().sleep(20);
} catch (Exception e) {
throw new RuntimeException(e);
}
PerformanceMonitor.end();
}
@Override
public void removeForum(int forumId) {
PerformanceMonitor.begin("com.yyq.proxy.ForumServiceImpl.removeForum");
System.out.println("模拟删除Forum记录:" + forumId);
try {
Thread.currentThread().sleep(40);
}catch (Exception e){
throw new RuntimeException(e);
}
PerformanceMonitor.end();
}
}
PerformanceMonitor:性能监视的实现类
package com.yyq.proxy; public class PerformanceMonitor {
private static ThreadLocal<MethodPerformance> performanceRecord = new ThreadLocal<MethodPerformance>();
public static void begin(String method) {
System.out.println("begin monitor...");
MethodPerformance mp = new MethodPerformance(method);
performanceRecord.set(mp);
}
public static void end(){
System.out.println("end monitor...");
MethodPerformance mp = performanceRecord.get();
mp.printPerformance();
}
}
MethodPerformance:记录性能监视信息
package com.yyq.proxy; public class MethodPerformance {
private long begin;
private long end;
private String serviceMethod;
public MethodPerformance(String serviceMethod){
this.serviceMethod = serviceMethod;
this.begin = System.currentTimeMillis();
}
public void printPerformance(){
end = System.currentTimeMillis();
long elapse = end - begin;
System.out.println(serviceMethod + "花费" + elapse + "毫秒。");
}
}
TestProxy.testForumService测试方法:
@Test
public void testForumService(){
ForumService forumService = new ForumServiceImpl();
forumService.removeForum(10);
forumService.removeTopic(1012);
}
package com.yyq.proxy;
public class ForumServiceImpl implements ForumService {
public void removeTopic(int topicId) {
System.out.println("模拟删除Topic记录:" + topicId);
try {
Thread.currentThread().sleep(20);
} catch (Exception e) {
throw new RuntimeException(e);
}
PerformanceMonitor.end();
} public void removeForum(int forumId) {
System.out.println("模拟删除Forum记录:" + forumId);
try {
Thread.currentThread().sleep(40);
}catch (Exception e){
throw new RuntimeException(e);
}
PerformanceMonitor.end();
}
}
PerformanceHandler:性能监视横切代码
package com.yyq.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class PerformanceHandler implements InvocationHandler {
private Object target; public PerformanceHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
PerformanceMonitor.begin(target.getClass().getName() + "." + method.getName());
Object obj = method.invoke(target, args);
PerformanceMonitor.end();
return obj;
}
}
@Test
public void testForumService2(){
ForumService target = new ForumServiceImpl();
PerformanceHandler handler = new PerformanceHandler(target);
ForumService proxy = (ForumService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),handler);
proxy.removeTopic(10);
proxy.removeForum(1012);
}
package com.yyq.proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz) {
enhancer.setSuperclass(clazz); //设置需要创建子类的
enhancer.setCallback(this);
return enhancer.create(); //通过字节码技术动态创建子类实例
}
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { //拦截父类所有方法的调用
PerformanceMonitor.begin(obj.getClass().getName() + "." + method.getName());
Object result = proxy.invokeSuper(obj, args); //通过代理类调用父类中的方法
PerformanceMonitor.end();
return result;
}
}
@Test
public void testForumService3(){
CglibProxy proxy = new CglibProxy();
ForumServiceImpl forumService = (ForumServiceImpl)proxy.getProxy(ForumServiceImpl.class);
forumService.removeForum(10);
forumService.removeTopic(1012);
}
Spring AOP基础知识的更多相关文章
- [Spring框架]Spring AOP基础入门总结一.
前言:前面已经有两篇文章讲了Spring IOC/DI 以及 使用xml和注解两种方法开发的案例, 下面就来梳理一下Spring的另一核心AOP. 一, 什么是AOP 在软件业,AOP为Aspect ...
- [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.
前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...
- CgLib动态代理学习【Spring AOP基础之一】
如果不了解JDK中proxy动态代理机制的可以先查看上篇文章的内容:Java动态代理学习[Spring AOP基础之一] 由于Java动态代理Proxy.newProxyInstance()的时候会发 ...
- 4-1 Spring框架基础知识
Spring框架基础知识 1.Spring 框架作用 主要解决了创建对象和管理对象的问题. 自动装配机制 2.Spring 框架 (Spring容器,JavaBean容器,Bean容器,Spring容 ...
- 【Spring】AOP实现原理(一):AOP基础知识
AOP相关概念 在学习AOP实现原理之前,先了解下AOP相关基础知识. AOP面向切面编程,它可以通过预编译方式或者基于动态代理对我们编写的代码进行拦截(也叫增强处理),在方法执行前后可以做一些操作, ...
- Spring框架基础知识
本人博客文章网址:https://www.peretang.com/basic-knowledge-of-spring-framework/ Spring框架简介 Spring , 一个开源的框架 , ...
- 【AOP】Spring AOP基础 + 实践 完整记录
Spring AOP的基础概念 ============================================================= AOP(Aspect-Oriented Pr ...
- Java动态代理学习【Spring AOP基础之一】
Spring AOP使用的其中一个底层技术就是Java的动态代理技术.Java的动态代理技术主要围绕两个类进行的 java.lang.reflect.InvocationHandler java.la ...
- Spring AOP基础概念及自定义注解式AOP初体验
对AOP的理解开始是抽象的,看到切点的匹配方式其实与正则表达式性质大致一样就基本了解AOP是基本是个什么作用了.只是整个概念更抽象,需要具化理解.下图列表是AOP相关概念解释,可能也比较抽象^_^ 比 ...
随机推荐
- 用Keytool和OpenSSL生成和签发数字证书
一)keytool生成私钥文件(.key)和签名请求文件(.csr),openssl签发数字证书 J2SDK在目录%JAVA_HOME%/bin提供了密钥库管理工具Keytool,用于管理密 ...
- 浅谈IT
在没有学计算机应用技术之前我对IT的认知度几乎为零,曾经还天真的认为IT就是白领,只要做上IT行业,以后便可高枕无忧.后来阴差阳错学了这个专业.通过一年的学习,虽然学艺不精但多少对IT行业了解的一知半 ...
- 【BZOJ】【3171】【TJOI2013】循环格
网络流/费用流 最后能走回出发点……说明全部是环= = 而二分图上的环说明什么呢……完备匹配 对于每个点,它都有四个可能的匹配点,且已知它已经(伪)匹配的一个点,那么我们于已知每条(伪)匹配边,我们连 ...
- DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
这个类型的resource 后面多个SRGB 表示SRGB空间是指gamma 矫正系数为2.2的色彩空间,这个问题我没有问别人,是我自己是上网查的,我觉得我不是个女人了......我又level up ...
- 用npm安装express后express命令找不到
Windows 平台加了 npm install -g express 也不行AppData\Roaming\npm 下面没有 express.bat 解决办法: sudo npm install - ...
- 查看Linux下*.a库文件中文件、函数、变量等情况
在Linux 下经常需要链接一些 *.a的库文件,那怎么查看这些*.a 中包 含哪些文件.函数.变量: 1. 查看文件:ar -t *.a 2. 查看函数.变里:nm *.a
- .NET设计模式(11):组合模式(Composite Pattern)(转)
概述 组合模式有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦. 意图 将对 ...
- sublime text3 插件安装
安装Package control 先打开安装代码的命令行 按 ctrl+~或者 view -> show console 将下面的代码粘贴到输入框里 按回车 import urllib.re ...
- 遭遇Asp.Net长文件名下载的问题和解决办法
在Asp.Net中写了一个附件上传和下载的程序,附件上传到数据库中,然后将附件的GUID保存起来,我们可以根据GUID来找到数据库中的附件,一般附件下载的代码是: <!--<br /> ...
- json 处理
//String sssssString = "{"response":{"data":[{"address":"南京市 ...