前景提要

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

  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. modelsim显示状态机名称的方法

    modelsim显示状态机名称的方法 2015-09-08 15:35 1414人阅读 评论(0) 收藏 举报  分类: FPGA基础知识(40)  版权声明:转载请注明出处:http://blog. ...

  2. 机器学习经典算法具体解释及Python实现--线性回归(Linear Regression)算法

    (一)认识回归 回归是统计学中最有力的工具之中的一个. 机器学习监督学习算法分为分类算法和回归算法两种,事实上就是依据类别标签分布类型为离散型.连续性而定义的. 顾名思义.分类算法用于离散型分布预測, ...

  3. Creating Dialogbased Windows Application (2) / 创建基于对话框的Windows应用程序(二)Button的应用、新建子窗体 / VC++, Windows

    创建基于对话框的Windows应用程序(二) —— Button的应用.新建子窗体 可以发现上一节创建的窗体中,点击OK和Cancel两个按钮是没有任何反应的.现在我们来为他们添加退出对话框的功能. ...

  4. python 第三方库下载地址

    http://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml

  5. 利用ascx输出knockoutjs的模板

    项目里面的UI模板在一个页面中有2K多行了.需要增加新的UI样式.问题来了.加上js代码,几乎是变成了不可维护的状态.增加和修改都需要用ctrl+f的方式找到对应的模板,然后进行处理.很容易出错.突然 ...

  6. 在海思hisiv100nptl平台上交叉编译并安装SRS

    ./configure --with-arm-ubuntu12 && make 须要安装: apt-get installgcc-arm-linux-gnueabi     ,但hi3 ...

  7. Spring MVC复选框

    以下示例显示如何在使用Spring Web MVC框架的表单中使用复选框(Checkbox).首先使用Eclipse IDE来创建一个WEB工程,并按照以下步骤使用Spring Web Framewo ...

  8. Classification week3: decision tree 笔记

    华盛顿大学 machine learnign :classification week 3 笔记 第二步: 注: 其中 ,mistake 的计算方法: 给定一个节点的数据集M,对每个特征hi(x),根 ...

  9. zoj2770 Burn the Linked Camp --- 差分约束

    有n个营地,每一个营地至多容纳Ci人.给出m个条件:第i到第j个营地之间至少有k人. 问n个营地总共至少有多少人. 此题显然差分约束.要求最小值.则建立x-y>=z方程组,建图求最长路. 用d[ ...

  10. Oracle Delete与系统资源

    在用Delete删除数据时,SQL语句首先要通过全表扫描或索引扫描找到符合条件的记录并删除. 然而在这个过程中将消耗大量的CPU资源,I/O资源以及UNDO数据. 如果删除的数据量较大,将极大的影响系 ...