- 浏览: 3012126 次
- 性别:
- 来自: 河南
文章分类
- 全部博客 (340)
- Java综合 (26)
- 程序人生 (53)
- RIA-ExtJS专栏 (18)
- RIA-mxGraph专栏 (4)
- RIA-Flex4专栏 (43)
- 框架-Spring专栏 (16)
- 框架-持久化专栏 (22)
- 框架-Struts2专栏 (11)
- 框架-Struts专栏 (12)
- SQL/NOSQL (12)
- 报表/图表 (2)
- 工作流 (5)
- XML专栏 (4)
- 日常报错解决方案 (5)
- Web前端-综合 (12)
- Web/JSP (14)
- Web前端-ajax专栏 (14)
- Web前端-JQuery专栏 (9)
- IDE技巧 (6)
- FILE/IO (14)
- 远程服务调用 (2)
- SSO单点登录 (2)
- 资源分享 (22)
- 云计算 (1)
- 项目管理 (3)
- php专栏 (1)
- Python专栏 (2)
- Linux (1)
- 缓存系统 (1)
- 队列服务器 (1)
- 网络编程 (0)
- Node.js (1)
最新评论
-
hui1989106a:
我的也不能解压,360和好压都试了,都不行
《Spring in Action》完整中文版分享下载 -
temotemo:
这些example有些过时了,官方建议使用HBase-1.0 ...
Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询 -
zy8102:
非常感谢~
HeadFirst系列之七:《深入浅出SQL》原版高清PDF电子书分享下载 -
zy8102:
重命名了一下搞定了
HeadFirst系列之七:《深入浅出SQL》原版高清PDF电子书分享下载 -
zy8102:
为什么下载以后老解压不了呢?
HeadFirst系列之七:《深入浅出SQL》原版高清PDF电子书分享下载
这篇文章紧接着上一篇静态代理和动态代理来说
前言:
到现在呢,老是讲动态代理,有的人都晕了,会说你这代理中用到的类怎么没有一个是与spring相关的呢,所以,我要说明的事,虽然现在讲的都是最普通的动态代理,但实质上就是将AOP的内部实现原理,Spring AOP之所以这么强大是因为它底层都是用动态代理来实现的,为了说明这一点,得贴出点源码来
1.如果是有接口声明的类进行AOP,spring调用的是java.lang.reflection.Proxy类来做处理
在spring的资源包中,找到org.springframework.aop.framework.JdkDynamicAopProxy这个类,在资源包的位置为spring-framework-2.5.6\src\org\springframework\aop\framework\JdkDynamicAopProxy.java,看看其中重要的代码片段
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
Class targetClass = this.advised.getTargetSource().getTargetClass();
logger.debug("Creating JDK dynamic proxy" +
(targetClass != null ? " for [" + targetClass.getName() + "]" : ""));
}
Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
再看org.springframework.aop.framework.ReflectiveMethodInvocation中的代码片段
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
2.如果是没有接口声明的类呢?SPRING通过CGLIB包和内部类来实现
private static class StaticUnadvisedInterceptor implements MethodInterceptor, Serializable {
private final Object target;
public StaticUnadvisedInterceptor(Object target) {
this.target = target;
}
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
Object retVal = methodProxy.invoke(target, args);
return massageReturnTypeIfNecessary(proxy, target, retVal);
}
}
/**
* Method interceptor used for static targets with no advice chain, when the
* proxy is to be exposed.
*/
private static class StaticUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {
private final Object target;
public StaticUnadvisedExposedInterceptor(Object target) {
this.target = target;
}
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
try {
oldProxy = AopContext.setCurrentProxy(proxy);
Object retVal = methodProxy.invoke(target, args);
return massageReturnTypeIfNecessary(proxy, target, retVal);
}
finally {
AopContext.setCurrentProxy(oldProxy);
}
}
}
/**
* Interceptor used to invoke a dynamic target without creating a method
* invocation or evaluating an advice chain. (We know there was no advice
* for this method.)
*/
private class DynamicUnadvisedInterceptor implements MethodInterceptor, Serializable {
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object target = advised.getTargetSource().getTarget();
try {
Object retVal = methodProxy.invoke(target, args);
return massageReturnTypeIfNecessary(proxy, target, retVal);
}
finally {
advised.getTargetSource().releaseTarget(target);
}
}
}
/**
* Interceptor for unadvised dynamic targets when the proxy needs exposing.
*/
private class DynamicUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
Object target = advised.getTargetSource().getTarget();
try {
oldProxy = AopContext.setCurrentProxy(proxy);
Object retVal = methodProxy.invoke(target, args);
return massageReturnTypeIfNecessary(proxy, target, retVal);
}
finally {
AopContext.setCurrentProxy(oldProxy);
advised.getTargetSource().releaseTarget(target);
}
}
}
好了,已经知道spring内部实现就是动态代理机制了,所以现在我们手动写的关于CGLIB的动态代理还是要写个小示例的。
上一篇文章中如果ServiceImpl没有实现任何接口的话,那么创建代理对象就不能使用javax.lang.Proxy这个类了,这时需要使用CGLIB了,在spring资源包中找到CGLIB的jar:spring-framework-2.5.6\lib\cglib\cglib-nodep-2.1_3.jar
然后写一个新的代理实现类CGlibProxyFactory.java
package com.javacrazyer.dao;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGlibProxyFactory implements MethodInterceptor {
private Object targetObject;
public Object newProxy(Object targetObject) {
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass());
enhancer.setCallback(this);
// 返回代理对象
return enhancer.create();
}
/**
* proxy 带来对象本身 method 被拦截到的方法 args 方法的参数 methodProxy 方法的代理对象
*/
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
checkSecurity();
Object ret = null;
try {
// 调用目标对象的真实方法
ret = method.invoke(this.targetObject, args);
// ret接受存在的返回值,不存在返回值则为Null
} catch (Exception e) {
e.printStackTrace();
}
return ret;
}
public void checkSecurity() {
System.out.println("--------ServiceImpl.checkSecurity()----------");
}
}
这时测试类有所变化
package com.javacrazyer.dao;
public class TestProxy {
public static void main(String[] args) {
CGlibProxyFactory hander = new CGlibProxyFactory();
//创建代理对象,这是这个代理对象是UserManagerImpl的子类
ServiceImpl service = (ServiceImpl)hander.newProxy(new ServiceImpl());
service.outPut();
service.putOut();
}
}
输出结果
--------ServiceImpl.checkSecurity()----------
I am method outPut
--------ServiceImpl.checkSecurity()----------
I am method putOut
到目前位置,无论是前面的静态代理,javax.lang.Proxy的动态代理,还是这里的CGLIB的动态代理都是没有借助任何框架的情况下实现AOP的方法
发表评论
-
Spring温习(9)--配置hibernate信息
2010-11-04 09:45 3119有时候为了为了操作方便,我们时常在spring整合hibern ... -
Spring温习(8)--国际化的支持
2010-11-03 11:07 3798我今天介绍的国际化呢,平时基本上都用不上,我的项目中也从来没用 ... -
Spring温习(7)--有关定时任务Quartz的示例
2010-11-02 23:07 2835实际项目中有关定时任务的使用还是比较普遍的,比如定时做报表,定 ... -
Spring温习(6)--邮件发送实现
2010-10-28 21:55 7683Spring对邮件发送支持的很好,我们只要配置好邮件发送器,写 ... -
Spring温习(4)--静态代理和动态代理
2010-10-27 11:27 3342代理模式分为静态代理和动态代理。静态代理就是我们自己定义的代理 ... -
Spring温习(3)--AutoWire自动装配
2010-10-27 09:48 3110在应用中,我们常常使用<ref>标签为JavaBe ... -
Spring温习(2)--IOC容器
2010-10-27 09:10 30551. Spring IoC的依赖注入 1) 使用构造方法来注入 ... -
Spring温习(1)--最基础的示例
2010-10-26 21:37 3499从现在开始,我将从Spring为起点,逐步复习几大框架各方面的 ... -
Spring事务管理的两种方式
2010-10-26 17:27 4039目前项目开发过程中对于Spring的事务管理,主要就这么两种方 ... -
Spring数据源配置的三种方式
2010-10-26 15:25 3788spring数据源配置目前确切的说应该分为:spring容器自 ... -
Spring AOP的两种实现方式
2010-10-26 11:18 5838AOP常用实现方式是一个采用声明的方式来实现,一个采用注解的方 ... -
Spring AOP原理及拦截器
2010-10-26 10:38 147920原理 AOP(Aspect Oriented Pro ... -
在MyEclipse8.5中恢复jpetstore项目
2010-10-22 17:24 2326恢复jpetstore项目的过程1.在myeclipse8.5 ... -
SpringMVC关键问题讲解
2010-10-21 21:31 22935接着上篇文章,大家可能关心的那两个问题 1.control ... -
SpringMVC入门实例及详细讲解
2010-10-21 20:48 215131Spring 框架提供了构建 Web 应用程序的 ...
相关推荐
"spring-cglib-repack-3.2.5.jar"、"spring-objenesis-repack-2.6.jar"和"spring-objenesis-repack-2.5.1.jar"这三个文件是Spring源码阅读环境中常用的依赖包,它们各自承担着不同的功能。 首先,我们来看"CGLIB"...
总的来说,`spring-cglib-repack-3.2.0.jar`和`spring-objenesis-repack-2.1.jar`是Spring框架正常运行的关键组成部分,它们分别负责动态子类生成和无参构造函数对象的快速实例化,对于理解和优化Spring应用的性能有...
配置CGLIB在Spring中的使用,一般不需要额外的配置,因为Spring默认会自动选择CGLIB或JDK动态代理,取决于目标类是否实现了接口。如果你想要显式指定使用CGLIB,可以在XML配置中加入以下代码: ```xml <aop:config>...
当Spring框架在进行AOP代理时,如果目标类没有实现接口,它会选择使用CGLIB来创建一个子类并动态地插入拦截器方法。CGLIB通过字节码操作技术生成代理类,这样就可以在运行时扩展或修改已有类的功能,而无需修改原始...
在提供的文件中,我们看到了两个与Spring相关的库:`spring-cglib-repack-3.2.6.jar` 和 `spring-objenesis-repack-2.6.jar`。这两个库都是Spring框架的重要组成部分,用于解决特定的编程问题。 首先,让我们来了解...
标题中的"spring-cglib-repack-3.2.5.jar"和"spring-objenesis-repack-2.6.jar"是两个与Spring框架相关的库文件,它们主要用于Spring框架的内部实现,尤其是针对Java对象的创建和代理机制。下面将详细解释这两个库的...
标题中的"spring-cglib-repack-3.2.5.jar"和"spring-objenesis-repack-2.6.jar"是Spring框架在运行时依赖的两个关键库,它们主要涉及到动态代理和对象创建的优化。 1. **CGLIB(Code Generation Library)**: ...
`spring-cglib-repack-3.2.6.jar` 包含了CGLIB库的重新打包版本,可能包含了针对Spring框架优化的特定实现,确保与Spring的其他组件无缝集成。 其次,`Objenesis` 是一个Java库,用于在没有默认构造函数的情况下...
总之,"spring-cglib-repack-3.1.jar"和"spring-objenesis-repack-2.1.jar"是Spring 4.0框架的重要组成部分,它们分别提供了动态子类生成和快速对象实例化的能力,对于理解Spring的内部机制,尤其是AOP和对象生命...
在Spring框架中,`spring-cglib-repack-3.2.6.jar`和`spring-objenesis-repack-2.6.jar`是两个重要的依赖库,它们在Spring源码环境中扮演着不可或缺的角色。本文将详细介绍这两个库以及它们在Spring框架中的作用。 ...
总之,`spring-cglib-repack-3.2.4.jar`和`spring-objenesis-repack-2.4.jar`在Spring框架中扮演着核心角色,主要负责AOP代理和复杂对象的实例化。了解这些库的作用和使用方法,有助于更好地理解和优化Spring应用。
本示例"spring-demo20-CGLIB动态代理.zip"主要展示了如何使用CGLIB库在Spring框架中实现动态代理。 CGLIB(Code Generation Library)是一个强大的高性能的代码生成库,它在许多AOP框架中被使用,如Spring AOP和...
总的来说,"spring-cglib-repack-3.2.0.jar"和"spring-objenesis-2.2.jar"是Spring框架中的关键组件,它们负责动态代理的实现,提高了代码的灵活性和可测试性。对这两个库的理解有助于提升对Spring框架整体运作机制...
总之,spring-cglib-repack-3.2.0.jar和spring-objenesis-repack-2.2.jar是Spring源码编译的关键组成部分,它们为Spring的AOP代理功能提供了底层支持,特别是对于没有实现接口的类。正确地包含这些库可以确保顺利...
总结,"spring-cglib-repack-3.2.5.jar" 和 "spring-objenesis-repack-2.5.1.jar" 是Spring框架中的重要组件,它们分别负责动态代理和无参实例化。了解这两个库的工作原理以及如何根据源码生成jar包,对于深入理解和...
Spring-asm-repack和Spring-cglib-repack是Spring框架为了实现动态代理和增强类功能所使用的库。 ASM是一个Java字节码操控和分析框架,它可以直接生成和修改类的字节码。在Spring中,ASM主要用于AOP(面向切面编程...
在Spring框架中,`spring-objenesis-repack-2.1.jar`和`spring-cglib-repack-3.1.jar`是两个关键的依赖库,它们在Spring的内部工作原理和功能扩展中扮演着重要角色。让我们深入探讨这两个库以及它们与Spring 4的关系...
spring-cglib-repack-3.2.6.jar 文件大小:313502 字节 修改时间:2018年8月26日 09:12:09 MD5 :1F3A42309EC16632954291B584778432 SHA1 :7A9601D36541798180C2AFC4DA34A78237F5C0AA CRC32 :675C7EB7 spring-...
5. **配置代理**:Spring会根据目标对象是否实现了接口来决定使用JDK动态代理还是CGLIB代理。如果目标对象实现了接口,Spring会选择JDK动态代理。动态代理类会继承自`java.lang.reflect.Proxy`,并实现目标对象的...
Spring框架是AOP实现的一个典范,它提供了两种主要的动态代理方式:JDK动态代理和CGLib动态代理。 **JDK动态代理**: JDK动态代理基于Java的反射API实现,适用于接口代理。当目标对象实现了至少一个接口时,Spring...