原创声明:本博客来源为本人原创作品,绝非他处摘取,转摘请联系博主

代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

动态代理实现主要有2种形式,主要分为:
1.jdk动态代理:
1)原理:是根据类加载器和接口创建代理类(此代理类是接口的实现类,所以必须使用接口 面向接口生成代理,位于java.lang.reflect包下)
2)实现方式:
1. 通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(…);
2. 通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});
3. 通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
4. 通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
2~4步骤可合并

package proxy.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import org.junit.Test; public class JDKProxy{
//写法1
private Object targetObject;//代理目标
public Object CustomerProxy(Object obj) {
targetObject = obj;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(),new targetHandler());
}
class targetHandler implements InvocationHandler{
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务...");
Object returnValue = method.invoke(targetObject, args);//回调被代理目标的方法userDaoImpl.add();
System.out.println("提交事务");
return returnValue;
}
}
public static void main(String[] args) {
JDKProxy jdkProxy = new JDKProxy();
Customer userDao = (Customer)jdkProxy.CustomerProxy(new CustomerImpl());
userDao.shopping();
}
//写法2
@Test
public void test1(){
Customer customer = new CustomerImpl();
Customer cus = (Customer) Proxy.newProxyInstance(customer.getClass().getClassLoader(), customer.getClass().getInterfaces(),new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
return method.invoke(proxy, args);
} });
cus.shopping();
}
}

3)不足点:jdk动态代理,必须是面向接口,目标业务类必须实现接口
2.CGLIB代理
1.原理:利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
2.实现方法:

package proxy.cglib;

import java.lang.reflect.Method;

import org.junit.Test;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import proxy.model.Customer; public class CGLIBProxy {
//写法1
private Object targetObject;
private Object createProxy(Object obj){
targetObject = obj;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetObject.getClass());//设置代理对象,父类,说明是继承,所有代理对象不能为final
enhancer.setCallback(new MyHandler());
return enhancer.create();//创建代理
}
class MyHandler implements MethodInterceptor{
@Override
public Object intercept(Object arg0, Method method, Object[] args,
MethodProxy arg3) throws Throwable {
System.out.println("开启事务..");
Object returnValue = method.invoke(targetObject, args);
System.out.println("提交事务....");
return returnValue;
}
}
@Test
public void test1() {
CGLIBProxy cglibProxy = new CGLIBProxy();
Customer customer = (Customer)cglibProxy.createProxy(new Customer());
customer.eat();
}
//写法2
@Test
public void test2(){
Customer customer = new Customer();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(customer.getClass());
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy arg3) throws Throwable {
if(method.getName().equals("eat")){
System.out.println("customer的eat方法被拦截了。。。。");
Object invoke = method.invoke(proxy, args);
System.out.println("真实方法拦截之后。。。。");
return invoke;
}
// 不拦截
return method.invoke(proxy, args);
}
});
Customer cus = (Customer) enhancer.create();
cus.eat();
}
}

3.注意点:被代理目标不是是final修饰的类(final修饰类不能被继承)
spring aop代理原理
1.注意点:

  • 如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
  • 如果目标对象实现了接口,可以强制使用CGLIB实现AOP
  • 如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

2.强制把jdk代理转换成cglib代理

  • 添加CGLIB库,SPRING_HOME/cglib/*.jar
  • 在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class = "true" />

传统AOP有默认的实现代理机制,可不需要专门指定代理,如自定义代理对象,可在类生成的时候自动代理,自动代理的方式主要有2种,一种是基于Bean名称的自动代理BeanNameAutoProxyCreator,另外一种是基于切面信息的自动代理DefaultAdvisorAutoProxyCreator

spring mvc 使用DefaultAdvisorAutoProxyCreator实现自动代理 配置

<!--定义一个表示声明使用自动代理的类  -->
<bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<!-- 定义代理类(本示例为异常类) -->
<bean id="exceptionHandler" class="com.kaizhi.platform.util.ExceptionHandler"/>
<!-- 定义支持正则表达式的通知 -->
<bean id="exceptionHandlerAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="exceptionHandler"/>
</property>
<property name="patterns">
<value>.save*.*</value>//正则匹配需要拦截的方法
</property>
</bean>

spring mvc 使用BeanNameAutoProxyCreator自动代理配

<!-- 基于BeanNameAutoProxyCreator,Bean名称的自动代理 -->
<!-- 定义代理类 -->
<bean id="exceptionHandler" class="com.kaizhi.platform.util.ExceptionHandler"/>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- 拦截的业务bean -->
<property name="beanNames" value="*adminFinanceService"/>
<!-- 拦截的通知 -->
<property name="interceptorNames" value="exceptionHandler"/>
</bean>

何为代理?jdk动态代理与cglib代理、spring Aop代理原理浅析的更多相关文章

  1. 动态代理:jdk动态代理和cglib动态代理

    /** * 动态代理类:先参考代理模式随笔,了解代理模式的概念,分为jdk动态代理和cglib,jdk动态代理是通过实现接口的方式创建代理类的,cglib是通过继承类的方式实现的代理类的 * jdk动 ...

  2. Spring 静态代理+JDK动态代理和CGLIB动态代理

    代理分为两种:静态代理 动态代理 静态代理:本质上会在硬盘上创建一个真正的物理类 动态代理:本质上是在内存中构建出一个类. 如果多个类需要进行方法增强,静态代理则需要创建多个物理类,占用磁盘空间.而动 ...

  3. 基于Spring AOP的JDK动态代理和CGLIB代理

    一.AOP的概念  在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...

  4. JDK动态代理和CGLib动态代理简单演示

    JDK1.3之后,Java提供了动态代理的技术,允许开发者在运行期间创建接口的代理实例. 一.首先我们进行JDK动态代理的演示. 现在我们有一个简单的业务接口Saying,如下: package te ...

  5. jdk动态代理与cglib代理、spring aop代理实现原理

    原创声明:本博客来源与本人另一博客[http://blog.csdn.net/liaohaojian/article/details/63683317]原创作品,绝非他处摘取 代理(proxy)的定义 ...

  6. jdk动态代理与cglib代理、spring aop代理实现原理解析

    原创声明:本博客来源为本人原创作品,绝非他处摘取,转摘请联系博主 代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象 ...

  7. 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。

    基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...

  8. JDK动态代理和CGLIB代理的区别

    一.原理区别: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. 而cglib动态代理是利用asm开源包,对代理对象类的class文件 ...

  9. Spring -- <tx:annotation-driven>注解基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)的区别。

    借鉴:http://jinnianshilongnian.iteye.com/blog/1508018 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional ...

随机推荐

  1. 1212: [HNOI2004]L语言

    1212: [HNOI2004]L语言 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 643  Solved: 252[Submit][Status] ...

  2. php基础语法(20161021)

    上午: 数据库总结: 1.创建数据库 create database 数据库名称 删除数据库 drop database 数据库名称 2.创建表 create table 表名 ( 列名 类型(长度) ...

  3. nao安装中文包教程

    本文介绍nao离线安装中文包 相官方索取 .demo 文件夹,里面包含很多的例程和中文包 下载winscp和putty(或者xshell),下载过程和安装我就不多说了,免费 把nao开机,连接路由器等 ...

  4. linux系统和Windows系统共存

    最近接触了linux系统,因为对linux系统一直存在一种敬畏之心,所以决定研究研究 那么今天我在这里呢是要和大家分享一下在Windows存在的情况下安装双系统linux 那么第一步呢,就是斤BIOS ...

  5. SSH里面使用jQuery的ajax

    今天我真的很兴奋!在我的SSH项目中用jQuery的异步传输成功了,经过一天多的奋战,大工告成! 我的项目需求是在javascript中向我的controller(即:action)中传输form表单 ...

  6. Linux网络那点事

    跨平台系列汇总:http://www.cnblogs.com/dunitian/p/4822808.html#linux 之前的之前说过网络自连接的配置(CentOS服务器网络配置:http://ww ...

  7. Vue.js 学习笔记 一

    本文的Demo和源代码已放到GitHub,如果您觉得本篇内容不错,请点个赞,或在GitHub上加个星星! https://github.com/zwl-jasmine95/Vue_test 以下所有知 ...

  8. 《Python基础教程》第2章读书笔记(1)

    # -*- coding:utf-8 -*- #最基本的数据结构:序列,索引从0开始 #python包括6种内建的序列 #最常用的序列包括:列表,元祖 #列表 edward = ['Edward Gu ...

  9. URL转换成二维码

    转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6685804.html 二维码已经成为我们日常生活中的一个不可获取的产物,火车票上,景区门票,超市付款等等都 ...

  10. 1132: 零起点学算法39——多组测试数据(a+b)

    1132: 零起点学算法39--多组测试数据(a+b) Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: ...