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相关概念解释,可能也比较抽象^_^ 比 ...
随机推荐
- Unity3D中灵活绘制进度条
有时我们需要在Unity3D中绘制进度条,如: 或 如果使用4.6版本以下的unity绘制环形的进度条可能需要费点劲.我搜到的大多数方法都是用NGUI插件,但有时只是 ...
- mono for andorid 引用外部的dll问题
这几天玩mono for android 心想,咱c#终于可以开发移动应用了,心里那个美啊------------ 先开发个什么呢,想起来前几天看到微博里一个用姓名笔画来算两个人关系的小测试,开发个这 ...
- JAVA 显示图片的简单源码 分类: Java Game 2014-08-14 10:10 77人阅读 评论(0) 收藏
此代码的原理就是用JLabel来加载图片,再将JLabel放入JFrame中, package com.mywork; import javax.swing.ImageIcon; import jav ...
- flex Chrome flash调试时 出现Shockwave flash has crashed的解决办法
在Chrome中输入:chrome://plugins/ PPAPI的Flash Player停用. 使用NPAPI的Flash player. 这里好像没有显示是Debug版本. 但是我在调 ...
- IE浏览器上传文件时本地路径变成”C:\fakepath\”的问题【转】
转自:http://www.iefans.net/ie-shangchuan-bendi-lujing-fakepath/ 在使用<input id="file_upl" t ...
- maven 常用5个命令
1. mvn help:describe 你是否因为记不清某个插件有哪些goal而痛苦过,你是否因为想不起某个goal有哪些参数而苦恼,那就试试这个命令吧,它会告诉你一切的. 参数: 1. -Dplu ...
- 13test07;字符排序,去重,三三输出
#include<iostream> #include<string> using namespace std; void buddle(char*,int);//对输入字符的 ...
- RDLC报表BC4000错误
如果RDLC报表报 BC4000错误,那是因为在矩阵外上面添加了文本框的缘故,导致系统不能读到RDLC报表表体,告诉你报表没有定义: 解决办法: 把表头文字放入矩阵中.
- Redis与Memcached的incr/decr差异对比
目前广泛使用的分布式缓存Redis和Memcached均支持对整数型Value值的增减,对应到具体命令中就是incr和decr命令. incr/decr是原子性操作(memcached 1.2.4及以 ...
- POJ 1488
#include <iostream> #include <string> using namespace std; int main() { string s; int i; ...