JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理,原理之前我已经讲过。JDK的动态代理用起来非常简单,但它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,该怎么办?现在我们可以使用CGLIB包。

PS:需要引入com.springsource.net.sf.cglib-2.2.0.jar包。

CGLIB是一个强大的高性能的代码生成包。它广泛的被许多AOP的框架使用,例如:Spring AOP和dynaop,为他们提供方法的interception(拦截); 它的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。 (CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。)

使用Cglib包生成代理的模板

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class CGLIBProxy implements MethodInterceptor {
 
private Object targetObject;//代理的目标对象
 
public Object createProxyInstance(Object targetObject){
 
this.targetObject = targetObject;
 
Enhancer enhancer = new Enhancer();//该类用于生成代理对象
 
enhancer.setSuperclass(this.targetObject.getClass());//设置父类
 
enhancer.setCallback(this);//设置回调用对象为本身
 
return enhancer.create();
 
}
 
public Object intercept(Object proxy, Method method, Object[] args,MethodProxy methodProxy) throws Throwable {
 
return methodProxy.invoke(this.targetObject, args);
 
}
 
}

第一个参数是代理对像,第二和第三个参数分别是拦截的方法和方法的参数。通过使用java.lang.reflect.Method对象的一般反射调用或者使用net.sf.cglib.proxy.MethodProxy对象调用都可以完成对原方法的调用,但是通常net.sf.cglib.proxy.MethodProxy对象被首选使用,因为它更快。

PS:net.sf.cglib.proxy.MethodProxy应该是cglib生成用来代替Method对象的一个对象,使用MethodProxy比调用JDK自身的Method直接执行方法效率会有提升。

示例:

Service类:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package net.zmcheng.service;
 
public class PersonService {
private String name;
public PersonService(){
super();
}
public PersonService(String name){
this.name = name;
}
public String getName() {
return name;
}
 
public void setName(String name) {
this.name = name;
}
public void save(){
   System.out.println("我是save方法");
  }
 
}

Cglib动态代理工厂:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package net.zmcheng.aop;
 
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import net.zmcheng.service.PersonService;
public class CglibProxyFactory implements MethodInterceptor{
public Object targetObject;
public Object createProxyIntance(Object targetObject){
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();//该类用于生成代理对象
enhancer.setSuperclass(this.targetObject.getClass());//设置父类
enhancer.setCallback(this);//设置回调用对象为本身
return enhancer.create();//创建代理对象
}
 
//MethodInterceptor接口类似于jdk中的java.lang.reflect.InvocationHandler接口
// MethodInterceptor中的intercept方法同java.lang.reflect.InvocationHandler接口中的 invoke方法类似
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy){//环绕通知
PersonService bean = (PersonService)this.targetObject;
Object result = null;
 
if(bean.getName()!=null){
//....advice()--->前置通知
 
try {
 
result = method.invoke(targetObject, args);
//..afteradvice()--->后置通知
 
} catch (Exception e) {
 
//....exceptionadvice()--->例外通知
 
e.printStackTrace();
}finally{
 
//finallyadvice();----->最终通知
}
 
}
return result;
}
}

测试类:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package net.zmcheng.test;
 
import org.junit.BeforeClass;
import org.junit.Test;
import net.zmcheng.aop.CglibProxyFactory;
import net.zmcheng.service.PersonService;
public class aopTest {
 
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
 
@Test
public void test() {
CglibProxyFactory factory = new CglibProxyFactory ();
PersonService service = (PersonService)factory.createProxyIntance(new PersonService("zmc"));
service.save();
}
}

输出结果:我是save方法

AOP中的概念:

Aspect(切面):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面横切性关注点的抽象.

joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器)

Pointcut(切入点):所谓切入点是指我们要对那些joinpoint进行拦截的定义.

Advice(通知):所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知

Target(目标对象):代理的目标对象

Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入.

Introduction(引入):在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.

Spring第九弹—使用CGLIIB实现AOP功能与AOP概念解释的更多相关文章

  1. (转)使用CGLIB实现AOP功能与AOP概念解释

    http://blog.csdn.net/yerenyuan_pku/article/details/52864395 使用CGLIB实现AOP功能 在Java里面,我们要产生某个对象的代理对象,这个 ...

  2. Ioc 之 Unity的AOP功能

    前面我们介绍了Unity的依赖注入功能,现在来介绍下Unity的AOP功能.AOP是面向切面编程,它能够使我们在不改变现有代码结构的情况下额外的为其添加一些功能. 我们还是使用配置文件来对类型进行注入 ...

  3. Spring AOP功能和目标

    1.AOP的作用 在OOP中,正是这种分散在各处且与对象核心功能无关的代码(横切代码)的存在,使得模块复用难度增加.AOP则将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可 ...

  4. spring AOP 之一:spring AOP功能介绍

    一.AOP简介 AOP:是一种面向切面的编程范式,是一种编程思想,旨在通过分离横切关注点,提高模块化,可以跨越对象关注点.Aop的典型应用即spring的事务机制,日志记录.利用AOP可以对业务逻辑的 ...

  5. Spring 框架的核心功能之AOP技术

    1. AOP 的概述 AOP, Aspect Oriented Programming, 面向切面编程; 通过预编译方式和运行期动态代理实现程序功能的统一维护的技术; AOP 采取横向抽取机制,取代了 ...

  6. Spring框架的核心功能之AOP技术

     技术分析之Spring框架的核心功能之AOP技术 AOP的概述        1. 什么是AOP的技术?        * 在软件业,AOP为Aspect Oriented Programming的 ...

  7. Spring第12篇—— Spring对Hibernate的SessionFactory的集成功能

    由于Spring和Hibernate处于不同的层次,Spring关心的是业务逻辑之间的组合关系,Spring提供了对他们的强大的管理能力, 而Hibernate完成了OR的映射,使开发人员不用再去关心 ...

  8. Spring AOP分析(1) -- 基本概念

    AOP全称是Aspect Oriented Programming,面向切面编程,是面向对象编程(OOP:Object Oriented Programming)的补充和完善.一般在系统中,OOP利用 ...

  9. 框架源码系列三:手写Spring AOP(AOP分析、AOP概念学习、切面实现、织入实现)

    一.AOP分析 问题1:AOP是什么? Aspect Oriented Programming 面向切面编程,在不改变类的代码的情况下,对类方法进行功能增强. 问题2:我们需要做什么? 在我们的框架中 ...

随机推荐

  1. GitHub 上 57 款最流行的开源深度学习项目【转】

    GitHub 上 57 款最流行的开源深度学习项目[转] 2017-02-19 20:09 334人阅读 评论(0) 收藏 举报 分类: deeplearning(28) from: https:// ...

  2. 十步理解Sql

    很多程序员视 SQL 为洪水猛兽.SQL 是一种为数不多的声明性语言,它的运行方式完全不同于我们所熟知的命令行语言.面向对象的程序语言.甚至是函数语言(尽管有些人认为 SQL 语言也是一种函数式语言) ...

  3. php -- 用文本来存储内容,file_put_contents,serialize,unserialize

    根据存储的内容来划分 字符串: file_put_contents :将一个字符串写入文件 语法:int file_put_contents ( string $filename , mixed $d ...

  4. Openwrt 移植hello world

    下载openwrt项目源代码.參考http://blog.csdn.net/u011641885/article/details/46348267 编译交叉工具链:进入工作文件夹,运行make men ...

  5. cx_Freeze的生成可执行文件

    ①.生成setup.py文件,仿照cx_Freeze给的例子 ②.python setup.py build 生成单个的可执行,会自动带着需要的动态链接库的.默认路径:build\bdist.win3 ...

  6. hdu 1421:搬寝室(动态规划 DP + 排序)

    搬寝室 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  7. 通过/proc/sys/net/ipv4/优化Linux下网络性能

    通过/proc/sys/net/ipv4/优化Linux下网络性能 /proc/sys/net/ipv4/优化1)      /proc/sys/net/ipv4/ip_forward该文件表示是否打 ...

  8. Linq循环DataTable,使用匿名对象取出需要的列

    var g_id = context.Request["g_id"]; DataTable dt = new DataTable(); var sql = @"selec ...

  9. 更改hadoop native库文件后datanode故障

    hadoop是用cloudra的官方yum源安装的,服务器是CentOS6.3 64位操作系统,自己写的mapreduce执行的时候hadoop会提示以下错误: WARN util.NativeCod ...

  10. 缺陷管理工具JIRA破解版及其安装方法

    JIRA是一个优秀的问题(or bugs,task,improvement,new feature )跟踪及管理软件.    它由Atlassian开发,采用J2EE技术.它正被广泛的开源软件组织,以 ...