004-搭建框架-实现AOP机制【一】代理技术
前景提要
监控方法性能、执行时间、记录日志等
AOP( Aspect Oriented Programming)面向方面编程。
在AOP中,需要定义一个Aspect(切面)类来编写需要横切业务的逻辑代码,例如上面提到的性能监控代码。此外,还需要通过一个条件来匹配想要拦截的类,这个条件在AOP中称为PointCut(切点)。
技术点
代理技术
使用Spring提供的AOP技术
使用动态代理技术实现AOP框架
使用ThreadLocal技术
数据库事物管理机制
使用AOP框架实现事物控制
一、代理技术
代理,Proxy。aop是代理的一种实现。Http代理等
1.1、静态代理
示例
public interface Hello {
void say(String name);
}
实现
public class HelloImpl implements Hello {
@Override
public void say(String name) {
System.out.println("Hello! " + name);
}
}
如,在说前后增加操作。
初级代理实现:
public class HelloProxy implements Hello {
private Hello hello;
public HelloProxy() {
this.hello = new HelloImpl();
}
@Override
public void say(String name) {
before();
hello.say(name);
after();
}
private void before(){
System.out.println("Before");
}
private void after(){
System.out.println("After");
}
}
测试主类:
Hello helloProxy = new HelloProxy();
helloProxy.say("muzixu");
输出:
Before
Hello! muzixu
After
其实,以上helloProxy 就是代理。
1.2、JDK动态代理
第一次 编写
使用JDK方案的一个动态代理
public class DynamicProxy implements InvocationHandler {
private Object target;
public DynamicProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(target,args);
after();
return result;
}
private void before(){
System.out.println("Before");
}
private void after(){
System.out.println("After");
}
}
在DynamicProxy 类中定义了一个Object的target变量,他就是被代理的目标对象。通过构造函数来初始化【即注入】。
该类实现了InvocationHandler 接口,需要实现的方法即invoke。在该方法中,直接通过反射去invoke method,在调用前后分别before,after,最后返回结果。
调用
Hello hello=new HelloImpl();
DynamicProxy dynamicProxy=new DynamicProxy(hello);
Hello helloProxy = (Hello)Proxy.newProxyInstance(hello.getClass().getClassLoader(),
hello.getClass().getInterfaces(),
dynamicProxy);
helloProxy.say("muzixu");
用通用的DynamicProxy 类去包装HelloImpl实例,然后在调用JDK提供的Proxy类的工厂方法newProxyInstance去动态的创建一个Hello接口的代理类,最后调度用这个代理类的方法。
结果同上一致。
第二次 优化
public class DynamicProxy2 implements InvocationHandler {
private Object target;
public DynamicProxy2(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(target, args);
after();
return result;
}
public <T> T getProxy() {
return (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
private void before() {
System.out.println("Before");
}
private void after() {
System.out.println("After");
}
}
使用
DynamicProxy2 dynamicProxy=new DynamicProxy2(new HelloImpl());
Hello helloProxy = dynamicProxy.getProxy();
helloProxy.say("muzixu");
其实就是将实例化过程抽象。
对比一下
| 名称 | 优点 | 缺点 |
| 静态代理 | 接口变了,实现类需要变,代理类也要变 | |
| JDK动态代理 | 接口变了,代理类不变 | 无法代理没有实现任何一个接口的类 |
| CGlib动态代理 |
运行期间动态生成字节码的工具 也就是动态生成代理类 |
1.3、CGlib动态代理
spring,hibernate等使用
pom:
<dependencies>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
</dependency>
</dependencies>
第一次实例
public class CGLibProxy implements MethodInterceptor {
public <T> T getProxy(Class<T> cls) {
return (T) Enhancer.create(cls,this);
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
before();
Object result = methodProxy.invokeSuper(o,objects);
after();
return result;
}
private void before() {
System.out.println("Before");
}
private void after() {
System.out.println("After");
}
}
使用
CGLibProxy proxy = new CGLibProxy();
Hello hello = proxy.getProxy(HelloImpl.class);
hello.say("muzixu");
第二次 单例模式构建
public class CGLibSingleProxy implements MethodInterceptor {
private static CGLibSingleProxy instance = new CGLibSingleProxy();
private CGLibSingleProxy(){
}
public static CGLibSingleProxy getInstance(){
return instance;
}
public <T> T getProxy(Class<T> cls) {
return (T) Enhancer.create(cls,this);
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
before();
Object result = methodProxy.invokeSuper(o,objects);
after();
return result;
}
private void before() {
System.out.println("Before");
}
private void after() {
System.out.println("After");
}
}
调用
Hello hello = CGLibSingleProxy.getInstance().getProxy(HelloImpl.class);
hello.say("muzixu");
004-搭建框架-实现AOP机制【一】代理技术的更多相关文章
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...
- 005-搭建框架-实现AOP机制【二】AOP技术
一.什么是AOP aspect-oriented programming,面向切面编程,对oop的一种补充. 著名示例,aspectj,spring+aspectj 二.aop之代码重构 2.1.代 ...
- SSM框架之AOP、动态代理、事务处理相关随笔
AOP: 原理:底层利用动态代理(两种动态代理技术都使用了) 两种实现方案: 第一种:JDK动态代理技术 实现的InvocationHandler接口,要想实现某个类的动态代理对象,必须有接口有实现类 ...
- Spring AOP 和 动态代理技术
AOP 是什么东西 首先来说 AOP 并不是 Spring 框架的核心技术之一,AOP 全称 Aspect Orient Programming,即面向切面的编程.其要解决的问题就是在不改变源代码的情 ...
- 006-搭建框架-实现AOP机制【三】AOP技术
2.3.spring+aspectj Spring在集成了aspectj后,同时也保留了以上的切面与代理的配置方式. 将Spring与aspectj集成与直接使用aspectj不同,不需要定义Aspe ...
- Castle框架中的IOC和AOP机制
反转控制(IOC)和面向切面编程(AOP)技术作为当前比较流行的技术,其优势已受到广泛关注,但是这两项新技术在实际项目上的应用研究却很落后,而且在.NET平台下实现这两项技术没有形成可以广泛套用的框架 ...
- [Spring框架]Spring AOP基础入门总结一.
前言:前面已经有两篇文章讲了Spring IOC/DI 以及 使用xml和注解两种方法开发的案例, 下面就来梳理一下Spring的另一核心AOP. 一, 什么是AOP 在软件业,AOP为Aspect ...
- 架构探险笔记5-使框架具备AOP特性(下)
开发AOP框架 借鉴SpringAOP的风格,写一个基于切面注解的AOP框架.在进行下面的步骤之前,确保已经掌了动态代理技术. 定义切面注解 /** * 切面注解 */ @Target(Element ...
- 10.Spring——框架的AOP
1.Spring 框架的 AOP 2.Spring 中基于 AOP 的 XML架构 3.Spring 中基于 AOP 的 @AspectJ 1.Spring 框架的 AOP Spring 框架的一个关 ...
随机推荐
- asp.net mvc 重定向
protected override void OnActionExecuting(ActionExecutingContext filterContext) { if (Request.Cookie ...
- C#实现svn server端的hook
目标 要做的东东呢,就是在向svn提交文件的时候,可以再server端读到所有提交文件的内容,并根据某些规则验证文件的合法性,如果验证失败,则终止提交,并在svn的客户端上显示错误信息. 准备工作 ...
- 整理了一下浅墨大神的Visual C++/DirectX 9.0c的游戏开发手记
还是非常棒的博客,只是没有一个文件夹.所以自己做了一个山寨文件夹在这里.便于随时查找. 前面31期从略. [Visual C++]游戏开发笔记三十二 浅墨DirectX提高班之中的一个 DirectX ...
- Atitit.upnp SSDP 查找nas的原理与实现java php c#.net c++
Atitit.upnp SSDP 查找nas的原理与实现java php c#.net c++ 1. 查找nas的原理1 2. 与dlna的关系1 3. 与ssdp的关系1 4. Cling - Ja ...
- 606. Construct String from Binary Tree 【easy】
606. Construct String from Binary Tree [easy] You need to construct a string consists of parenthesis ...
- 557. Reverse Words in a String III【easy】
557. Reverse Words in a String III[easy] Given a string, you need to reverse the order of characters ...
- python 分支结构
if 语句 if语句 计算机之所以能做很多自动化的任务,因为它可以自己做条件判断. 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,可以用if语句实现: age = 20 if ag ...
- Extjs中获取getEl获取undefined的问题
一定注意: getEl()方法只有在panel.show()之后才会有值.在hide()的时候没有该对象. 也就是说如果要操作Ext.dom.Element对象必须让对象先显示出来.
- python升级导致yum命令无法使用的解决
1.报错信息如下: [root@develop bin]# yum [root@develop local]# yum -y install prce There was a problem impo ...
- Java基础04 封装与接口(转载)
数据成员和方法都是同时开放给内部和外部的.在对象内部,我们利用this来调用对象的数据成员和方法.在对象外部,比如当我们在另一个类中调用对象的时,可以使用 对象.数据成员 和 对象.方法() 来调用对 ...