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. 02 观察 mysql 周期性变化

    ()首先写一个shell 脚本 vim mysql_status.sh 脚本如下: #!bin/bash while true do mysqladmin -urooy ext|awk '/Queri ...

  2. Bitcoin: A Peer-to-Peer Electronic Cash System(比特币论文翻译)

    比特币历史: 2008年,比特币论文诞生 2009年1月,第一批比特币诞生 2011年4月,比特币价格第一次达到了1美元 2011年6月,涨到30美元,然后开始跌 2013年1月,4美元 2013年1 ...

  3. php -- 魔术方法 之 删除属性:__unset()

    属性重载:当访问一个不存在或者权限不够的属性的时候,能够触发一系列的魔术方法,就叫做属性重载 __unset():当删除一个不存在或者权限不够的属性的时候会自动触发 <?php //属性重载 c ...

  4. xampp默认项目文件夹htdocs

    正确安装好XAMPP后,默认是必须将php程序放到 xampp\htdocs文件夹下才能运行但可以修改.. 参考:http://zhidao.baidu.com/link?url=sY_DPSeGBA ...

  5. UIViewController三种不同的初始化view的方式

    You can specify the views for a view controller using a Storyboard created in Interface Builder. A s ...

  6. cocos2dx游戏--三国关羽传【角色扮演类】Demo的制作及实现

    项目地址:https://github.com/moonlightpoet/GuanYuZhuan 主要类及其对应效果: MainScene:菜单界面(用于选择不同剧本) StoryScene:故事界 ...

  7. oracle数据库查询时间sql

    select * from cc_picture_info where PICTURE_SOURCE = 3 AND UPLOAD_TIME > to_date('2017-03-29 16:5 ...

  8. Course Selection CodeChef - RIN

    All submissions for this problem are available. Read problems statements in Mandarin Chineseand Russ ...

  9. 《从零开始学Swift》学习笔记(Day 70)——Swift与Objective-C混合编程之Swift与Objective-C API映射

    原创文章,欢迎转载.转载请注明:关东升的博客 Swift与Objective-C API映射 在混合编程过程中Swift与Objective-C调用是双向的,由于不同语言对于相同API的表述是不同的, ...

  10. log4j日志服务器配置

    可参考的文章: http://www.jb51.net/article/89597.htm http://www.jb51.net/article/41001.htm http://liuzhijun ...