前景提要

  监控方法性能、执行时间、记录日志等

  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机制【一】代理技术的更多相关文章

  1. Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架

    类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...

  2. 005-搭建框架-实现AOP机制【二】AOP技术

    一.什么是AOP aspect-oriented  programming,面向切面编程,对oop的一种补充. 著名示例,aspectj,spring+aspectj 二.aop之代码重构 2.1.代 ...

  3. SSM框架之AOP、动态代理、事务处理相关随笔

    AOP: 原理:底层利用动态代理(两种动态代理技术都使用了) 两种实现方案: 第一种:JDK动态代理技术 实现的InvocationHandler接口,要想实现某个类的动态代理对象,必须有接口有实现类 ...

  4. Spring AOP 和 动态代理技术

    AOP 是什么东西 首先来说 AOP 并不是 Spring 框架的核心技术之一,AOP 全称 Aspect Orient Programming,即面向切面的编程.其要解决的问题就是在不改变源代码的情 ...

  5. 006-搭建框架-实现AOP机制【三】AOP技术

    2.3.spring+aspectj Spring在集成了aspectj后,同时也保留了以上的切面与代理的配置方式. 将Spring与aspectj集成与直接使用aspectj不同,不需要定义Aspe ...

  6. Castle框架中的IOC和AOP机制

    反转控制(IOC)和面向切面编程(AOP)技术作为当前比较流行的技术,其优势已受到广泛关注,但是这两项新技术在实际项目上的应用研究却很落后,而且在.NET平台下实现这两项技术没有形成可以广泛套用的框架 ...

  7. [Spring框架]Spring AOP基础入门总结一.

    前言:前面已经有两篇文章讲了Spring IOC/DI 以及 使用xml和注解两种方法开发的案例, 下面就来梳理一下Spring的另一核心AOP. 一, 什么是AOP 在软件业,AOP为Aspect ...

  8. 架构探险笔记5-使框架具备AOP特性(下)

    开发AOP框架 借鉴SpringAOP的风格,写一个基于切面注解的AOP框架.在进行下面的步骤之前,确保已经掌了动态代理技术. 定义切面注解 /** * 切面注解 */ @Target(Element ...

  9. 10.Spring——框架的AOP

    1.Spring 框架的 AOP 2.Spring 中基于 AOP 的 XML架构 3.Spring 中基于 AOP 的 @AspectJ 1.Spring 框架的 AOP Spring 框架的一个关 ...

随机推荐

  1. hdu 3641 数论 二分求符合条件的最小值数学杂题

    http://acm.hdu.edu.cn/showproblem.php?pid=3641 学到: 1.二分求符合条件的最小值 /*================================= ...

  2. oracle10g安装,卸载

    一.安装 1.因为oracle的特殊性,笔者选择通过虚拟机安装windows7旗舰版安装数据库,大家的系统假设是windows xp.windows 7,windows 8能够直接安装,windows ...

  3. Android中Intent传递类对象的方法一(Serializable)

    Activity之间通过Intent传递值,支持基本数据类型和String对象及它们的数组对象byte.byte[].char.char[].boolean.boolean[].short.short ...

  4. C++语言基础(1)-命名空间

    一个中大型软件往往由多名程序员共同开发,会使用大量的变量和函数,当有两个人都同时定义了一个名字相同的全局变量或函数的时候,若是把他们的代码整合在一块编译,此时编译器就会提示变量或函数重复定义,C++为 ...

  5. C#动态调用WCF接口(2)

    如何使用 1.第一种方式比较简单,而且也是大家喜欢的,因为不需要任何配置文件就可解决,只需知道服务契约接口和服务地址就可以调用. 2.使用Invoke的方式,但是需要在调用客户端配置WCF,配置后在I ...

  6. mac 火狐 下载 任何文件都是失败

    今天在从邮件中下载附件,怎么点击下载 浏览器上都是失败 最后突然想到,我改过火狐的下载路径,改到根目录下了,根目录下应该是没有权限保存文件的 后把下载路径改成 “下载” 就可以正常下载了

  7. Codeforces 460E Roland and Rose(暴力)

    题目链接:Codeforces 460E Roland and Rose 题目大意:在以原点为圆心,半径为R的局域内选择N个整数点,使得N个点中两两距离的平方和最大. 解题思路:R最大为30.那么事实 ...

  8. MFC invalidate和RedrawWindow区别

    Invalidate()函数是强制系统进行重画,但是不一定就马上进行重画.因为Invalidate()只是通知系统,此时的窗口已经变为无效.强制系统调用WM_PAINT,而这个消息只是Post就是将该 ...

  9. centos5/6/7下yum安装zabbix-agent(被控端)

    由于之前安装都是拷贝同事的zabbix_agent.tar.gz包,可是我在网上找了一大圈都没有找到这个tar包是从哪里来的,毕竟新手,太笨...so最后自己排错,找到了比较便捷的方式,直接通过yum ...

  10. 支付宝热补丁技术— AndFix原理[阿里Hao]

    本文由嵌入式企鹅圈原创团队成员.阿里资深project师Hao分享. 上次我们介绍了用dexposed方案实施热补丁的原理.它本质上就是hook要改动的函数.这样一来在正式版本号公布时就不能直接拿热补 ...