`
wanjianfei
  • 浏览: 325480 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

CGlib简单介绍

阅读更多

CGlib简单介绍

CGlib概述:
cglib(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。
cglib封装了asm,可以在运行期动态生成新的class。
cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。

CGlib应用:
以一个实例在简单介绍下cglib的应用。
我们模拟一个虚拟的场景,关于信息的管理。

1)原始需求是任何人可以操作信息的create,update,delete,query操作。
InfoManager.java--封装对信息的操作

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassInfoManager{
//模拟查询操作
publicvoidquery(){
System.out.println(
"query");
}
//模拟创建操作
publicvoidcreate(){
System.out.println(
"create");
}
//模拟更新操作
publicvoidupdate(){
System.out.println(
"update");
}
//模拟删除操作
publicvoiddelete(){
System.out.println(
"delete");
}
}

InfoManagerFactory.java--工厂类

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassInfoManagerFactory{
privatestaticInfoManagermanger=newInfoManager();
/**
*创建原始的InfoManager
*
*
@return
*/
publicstaticInfoManagergetInstance(){
returnmanger;
}
}

client.java--供客户端调用

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassClient{

publicstaticvoidmain(String[]args){
Clientc
=newClient();
c.anyonecanManager();
}

/**
*模拟:没有任何权限要求,任何人都可以操作
*/
publicvoidanyonecanManager(){
System.out.println(
"anyonecandomanager");
InfoManagermanager
=InfoManagerFactory.getInstance();
doCRUD(manager);
separatorLine();
}

/**
*对Info做增加/更新/删除/查询操作
*
*
@parammanager
*/
privatevoiddoCRUD(InfoManagermanager){
manager.create();
manager.update();
manager.delete();
manager.query();
}

/**
*加一个分隔行,用于区分
*/
privatevoidseparatorLine(){
System.out.println(
"################################");
}

}

至此,没有涉及到cglib的内容,因为需求太简单了,但是接下来,需求发生了改变,要求:

2)只有一个叫“maurice”的用户登录,才允许对信息进行create,update,delete,query的操作。
怎么办?难道在每个方法前,都加上一个权限判断吗?这样重复逻辑太多了,于是乎想到了Proxy(代理模式),但是原先的InfoManager也没有实现接口,不能采用jdk的proxy。那么cglib在这边就要隆重登场。
一旦使用cgblig,只需要添加一个MethodInterceptor的类以及修改factory代码就可以实现这个需求。
AuthProxy.java--权限校验代理类

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassAuthProxyimplementsMethodInterceptor{

privateStringname;//会员登录名

publicAuthProxy(Stringname){
this.name=name;
}

/**
*权限校验,如果会员名为:maurice,则有权限做操作,否则提示没有权限
*/
@Override
publicObjectintercept(Objectobj,Methodmethod,Object[]args,MethodProxyproxy)throwsThrowable{
if(!"maurice".equals(this.name)){
System.out.println(
"AuthProxy:youhavenopermitstodomanager!");
returnnull;
}
returnproxy.invokeSuper(obj,args);
}

publicStringgetName(){
returnname;
}

publicvoidsetName(Stringname){
this.name=name;
}

}

InfoManagerFactory.java--代码变动如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassInfoManagerFactory{

/**
*创建带有权限检验的InfoManager
*
*
@paramauth
*
@return
*/
publicstaticInfoManagergetAuthInstance(AuthProxyauth){
Enhancerenhancer
=newEnhancer();
enhancer.setSuperclass(InfoManager.
class);
enhancer.setCallback(auth);
return(InfoManager)enhancer.create();
}


}

client.java--代码修改如下

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassClient{

publicstaticvoidmain(String[]args){
Clientc
=newClient();
c.haveNoAuthManager();
c.haveAuthManager();
}

/**
*模拟:登录会员没有权限
*/
publicvoidhaveNoAuthManager(){
System.out.println(
"theloginer'snameisnotmaurice,sohavenopermitsdomanager");
InfoManagernoAuthManager
=InfoManagerFactory.getAuthInstance(newAuthProxy("maurice1"));
doCRUD(noAuthManager);
separatorLine();
}

/**
*模拟:登录会员有权限
*/
publicvoidhaveAuthManager(){
System.out.println(
"theloginer'snameismaurice,sohavepermitsdomanager");
InfoManagerauthManager
=InfoManagerFactory.getAuthInstance(newAuthProxy("maurice"));
doCRUD(authManager);
separatorLine();
}

/**
*对Info做增加/更新/删除/查询操作
*
*
@parammanager
*/
privatevoiddoCRUD(InfoManagermanager){
manager.create();
manager.update();
manager.delete();
manager.query();
}

/**
*加一个分隔行,用于区分
*/
privatevoidseparatorLine(){
System.out.println(
"################################");
}

}

执行下代码,发现这时client端中已经加上了权限校验。
同样是InfoManager,为什么这时能多了权限的判断呢?Factory中enhancer.create()返回的到底是什么对象呢?这个疑问将在第三部分CGlib中解释。
这边的代码,其实是介绍了cglib中的enhancer功能.

到这里,参照上面的代码,就可以使用cglib带来的aop功能了。但是为了更多介绍下cglib的功能,模拟需求再次发生变化:

3)由于query功能用户maurice才能使用,招来其他用户的强烈的抱怨,所以权限再次变更,只有create,update,delete,才需要权限保护,query任何人都可以使用。
怎么办?采用AuthProxy,使得InfoManager中的所有方法都被代理,加上了权限的判断。当然,最容易想到的办法,就是在AuthProxy的intercept的方法中再做下判断,如果代理的method是query,不需要权限验证。这么做,可以,但是一旦逻辑比较复杂的时候,intercept这个方法要做的事情会很多,逻辑会异常的复杂。
幸好,cglib还提供了CallbackFilter。使用CallbackFilter,可以明确表明,被代理的类(InfoManager)中不同的方法,被哪个拦截器(interceptor)拦截。
AuthProxyFilter.java

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassAuthProxyFilterimplementsCallbackFilter{

privatestaticfinalintAUTH_NEED=0;
privatestaticfinalintAUTH_NOT_NEED=1;

/**
*<pre>
*选择使用的proxy
*如果调用query函数,则使用第二个proxy
*否则,使用第一个proxy
*</pre>
*/
@Override
publicintaccept(Methodmethod){
if("query".equals(method.getName())){
returnAUTH_NOT_NEED;
}
returnAUTH_NEED;
}

}

这段代码什么意思?其中的accept方法的意思是说,如果代理的方法是query(),那么使用第二个拦截器去拦截,如果代理的方法不是query(),那么使用第一个拦截器去拦截。所以我们只要再写一个拦截器,不做权限校验就行了。(其实,cglib中的NoOp.INSTANCE就是一个空的拦截器,只要配置上这个就可以了。)
InfoManagerFactory.java--代码修改如下:(配置不同的拦截器和filter)

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassInfoManagerFactory{

/**
*创建不同权限要求的InfoManager
*
*
@paramauth
*
@return
*/
publicstaticInfoManagergetSelectivityAuthInstance(AuthProxyauth){
Enhancerenhancer
=newEnhancer();
enhancer.setSuperclass(InfoManager.
class);
enhancer.setCallbacks(
newCallback[]{auth,NoOp.INSTANCE});
enhancer.setCallbackFilter(
newAuthProxyFilter());
return(InfoManager)enhancer.create();
}

}

记住:setCallbacks中的拦截器(interceptor)的顺序,一定要和CallbackFilter里面指定的顺序一致!!切忌。

Client.java

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicclassClient{

publicstaticvoidmain(String[]args){
Clientc
=newClient();
c.selectivityAuthManager();
}

/**
*模拟:没有权限的会员,可以作查询操作
*/
publicvoidselectivityAuthManager(){
System.out.println(
"theloginer'snameisnotmaurice,sohavenopermitsdomanagerexceptdoqueryoperator");
InfoManagerauthManager
=InfoManagerFactory.getSelectivityAuthInstance(newAuthProxy("maurice1"));
doCRUD(authManager);
separatorLine();
}

/**
*对Info做增加/更新/删除/查询操作
*
*
@parammanager
*/
privatevoiddoCRUD(InfoManagermanager){
manager.create();
manager.update();
manager.delete();
manager.query();
}

/**
*加一个分隔行,用于区分
*/
privatevoidseparatorLine(){
System.out.println(
"################################");
}

}

此时,对于query的权限校验已经被去掉了。


通过一个模拟需求,简单介绍了cglib aop功能的使用。
CGlib应用非常广,在spring,hibernate等框架中,被大量的使用。


CGlib原理:
cglib神奇吗?其实一旦了解cglib enhancer的原理,一切就真相大白了。
刚才在第二部分中,有个疑问:enhancer.create()到底返回了什么对象?

其实在刚才的例子中,cglib在代码运行期,动态生成了InfoManager的子类,并且根据CallbackFilter的accept方法,覆写了InfoManager中的所有方法--去执行相应的MethodInterceptor的intercept方法。

有兴趣的朋友可以看看我反编译的InfoManager的子类,就可以很明白知道具体的实现了。(需要有耐心才可以)
InfoManager$$EnhancerByCGLIB$$de624598.jad

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->//DecompiledbyJadv1.5.8e.Copyright2001PavelKouznetsov.
//Jadhomepage:http://www.geocities.com/kpdus/jad.html
//Decompileroptions:packimports(3)
//SourceFileName:<generated>

packagecn.eulic.codelab.cglib;

importjava.lang.reflect.Method;
importnet.sf.cglib.core.Signature;
importnet.sf.cglib.proxy.*;

//Referencedclassesofpackagecn.eulic.codelab.cglib:
//InfoManager

publicclassCGLIB.BIND_CALLBACKSextendsInfoManager
implementsFactory
{

staticvoidCGLIB$STATICHOOK1()
{
Classclass1;
ClassLoaderclassloader;
CGLIB$THREAD_CALLBACKS
=newThreadLocal();
classloader
=(class1=Class.forName("cn.eulic.codelab.cglib.InfoManager$$EnhancerByCGLIB$$de624598")).getClassLoader();
classloader;
CGLIB$emptyArgs
=newObject[0];
CGLIB$delete$
0$Proxy=MethodProxy.create(classloader,(CGLIB$delete$0$Method=Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("delete",newClass[0])).getDeclaringClass(),class1,"()V","delete","CGLIB$delete$0");
CGLIB$create$
1$Proxy=MethodProxy.create(classloader,(CGLIB$create$1$Method=Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("create",newClass[0])).getDeclaringClass(),class1,"()V","create","CGLIB$create$1");
CGLIB$query$
2$Proxy=MethodProxy.create(classloader,(CGLIB$query$2$Method=Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("query",newClass[0])).getDeclaringClass(),class1,"()V","query","CGLIB$query$2");
CGLIB$update$
3$Proxy=MethodProxy.create(classloader,(CGLIB$update$3$Method=Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("update",newClass[0])).getDeclaringClass(),class1,"()V","update","CGLIB$update$3");
CGLIB$finalize$
4$Proxy=MethodProxy.create(classloader,(CGLIB$finalize$4$Method=Class.forName("java.lang.Object").getDeclaredMethod("finalize",newClass[0])).getDeclaringClass(),class1,"()V","finalize","CGLIB$finalize$4");
CGLIB$hashCode$
5$Proxy=MethodProxy.create(classloader,(CGLIB$hashCode$5$Method=Class.forName("java.lang.Object").getDeclaredMethod("hashCode",newClass[0])).getDeclaringClass(),class1,"()I","hashCode","CGLIB$hashCode$5");
CGLIB$clone$
6$Proxy=MethodProxy.create(classloader,(CGLIB$clone$6$Method=Class.forName("java.lang.Object").getDeclaredMethod("clone",newClass[0])).getDeclaringClass(),class1,"()Ljava/lang/Object;","clone","CGLIB$clone$6");
CGLIB$equals$
7$Proxy=MethodProxy.create(classloader,(CGLIB$equals$7$Method=Class.forName("java.lang.Object").getDeclaredMethod("equals",newClass[]{
Class.forName(
"java.lang.Object")
})).getDeclaringClass(),class1,
"(Ljava/lang/Object;)Z","equals","CGLIB$equals$7");
CGLIB$toString$
8$Proxy=MethodProxy.create(classloader,(CGLIB$toString$8$Method=Class.forName("java.lang.Object").getDeclaredMethod("toString",newClass[0])).getDeclaringClass(),class1,"()Ljava/lang/String;","toString","CGLIB$toString$8");
return;
}

finalvoidCGLIB$delete$0()
{
super.delete();
}

publicfinalvoiddelete()
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0!=null)goto_L2;elsegoto_L1
_L1:
JVMINSTRpop;
CGLIB$BIND_CALLBACKS(
this);
CGLIB$CALLBACK_0;
_L2:
JVMINSTRdup;
JVMINSTRifnull
37;
goto_L3_L4
_L3:
breakMISSING_BLOCK_LABEL_21;
_L4:
breakMISSING_BLOCK_LABEL_37;
this;
CGLIB$delete$
0$Method;
CGLIB$emptyArgs;
CGLIB$delete$
0$Proxy;
intercept();
return;
super.delete();
return;
}

finalvoidCGLIB$create$1()
{
super.create();
}

publicfinalvoidcreate()
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0!=null)goto_L2;elsegoto_L1
_L1:
JVMINSTRpop;
CGLIB$BIND_CALLBACKS(
this);
CGLIB$CALLBACK_0;
_L2:
JVMINSTRdup;
JVMINSTRifnull
37;
goto_L3_L4
_L3:
breakMISSING_BLOCK_LABEL_21;
_L4:
breakMISSING_BLOCK_LABEL_37;
this;
CGLIB$create$
1$Method;
CGLIB$emptyArgs;
CGLIB$create$
1$Proxy;
intercept();
return;
super.create();
return;
}

finalvoidCGLIB$query$2()
{
super.query();
}

publicfinalvoidquery()
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0!=null)goto_L2;elsegoto_L1
_L1:
JVMINSTRpop;
CGLIB$BIND_CALLBACKS(
this);
CGLIB$CALLBACK_0;
_L2:
JVMINSTRdup;
JVMINSTRifnull
37;
goto_L3_L4
_L3:
breakMISSING_BLOCK_LABEL_21;
_L4:
breakMISSING_BLOCK_LABEL_37;
this;
CGLIB$query$
2$Method;
CGLIB$emptyArgs;
CGLIB$query$
2$Proxy;
intercept();
return;
super.query();
return;
}

finalvoidCGLIB$update$3()
{
super.update();
}

publicfinalvoidupdate()
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0!=null)goto_L2;elsegoto_L1
_L1:
JVMINSTRpop;
CGLIB$BIND_CALLBACKS(
this);
CGLIB$CALLBACK_0;
_L2:
JVMINSTRdup;
JVMINSTRifnull
37;
goto_L3_L4
_L3:
breakMISSING_BLOCK_LABEL_21;
_L4:
breakMISSING_BLOCK_LABEL_37;
this;
CGLIB$update$
3$Method;
CGLIB$emptyArgs;
CGLIB$update$
3$Proxy;
intercept();
return;
super.update();
return;
}

finalvoidCGLIB$finalize$4()
throwsThrowable
{
super.finalize();
}

protectedfinalvoidfinalize()
throwsThrowable
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0!=null)goto_L2;elsegoto_L1
_L1:
JVMINSTRpop;
CGLIB$BIND_CALLBACKS(
this);
CGLIB$CALLBACK_0;
_L2:
JVMINSTRdup;
JVMINSTRifnull
37;
goto_L3_L4
_L3:
breakMISSING_BLOCK_LABEL_21;
_L4:
breakMISSING_BLOCK_LABEL_37;
this;
CGLIB$finalize$
4$Method;
CGLIB$emptyArgs;
CGLIB$finalize$
4$Proxy;
intercept();
return;
super.finalize();
return;
}

finalintCGLIB$hashCode$5()
{
returnsuper.hashCode();
}

publicfinalinthashCode()
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0!=null)goto_L2;elsegoto_L1
_L1:
JVMINSTRpop;
CGLIB$BIND_CALLBACKS(
this);
CGLIB$CALLBACK_0;
_L2:
JVMINSTRdup;
JVMINSTRifnull
52;
goto_L3_L4
_L3:
this;
CGLIB$hashCode$
5$Method;
CGLIB$emptyArgs;
CGLIB$hashCode$
5$Proxy;
intercept();
JVMINSTRdup;
JVMINSTRifnonnull
45;
goto_L5_L6
_L5:
JVMINSTRpop;
0;
goto_L7
_L6:
(Number);
intValue();
_L7:
return;
_L4:
returnsuper.hashCode();
}

finalObjectCGLIB$clone$6()
throwsCloneNotSupportedException
{
returnsuper.clone();
}

protectedfinalObjectclone()
throwsCloneNotSupportedException
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0!=null)goto_L2;elsegoto_L1
_L1:
JVMINSTRpop;
CGLIB$BIND_CALLBACKS(
this);
CGLIB$CALLBACK_0;
_L2:
JVMINSTRdup;
JVMINSTRifnull
37;
goto_L3_L4
_L3:
this;
CGLIB$clone$
6$Method;
CGLIB$emptyArgs;
CGLIB$clone$
6$Proxy;
intercept();
return;
_L4:
returnsuper.clone();
}

finalbooleanCGLIB$equals$7(Objectobj)
{
returnsuper.equals(obj);
}

publicfinalbooleanequals(Objectobj)
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0!=null)goto_L2;elsegoto_L1
_L1:
JVMINSTRpop;
CGLIB$BIND_CALLBACKS(
this);
CGLIB$CALLBACK_0;
_L2:
JVMINSTRdup;
JVMINSTRifnull
57;
goto_L3_L4
_L3:
this;
CGLIB$equals$
7$Method;
newObject[]{
obj
};
CGLIB$equals$
7$Proxy;
intercept();
JVMINSTRdup;
JVMINSTRifnonnull
50;
goto_L5_L6
_L5:
JVMINSTRpop;
false;
goto_L7
_L6:
(Boolean);
booleanValue();
_L7:
return;
_L4:
returnsuper.equals(obj);
}

finalStringCGLIB$toString$8()
{
returnsuper.toString();
}

publicfinalStringtoString()
{
CGLIB$CALLBACK_0;
if(CGLIB$CALLBACK_0!=null)goto_L2;<s
分享到:
评论

相关推荐

    cglib动态代理介绍

    下面是一个简单的CGlib动态代理的示例: ```java import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method;...

    cglib.zip

    下面将详细介绍CGLib的相关知识点。 1. **动态代理**: CGLib常用于为Java对象创建代理,以在方法调用前后添加额外的行为。比如,在Spring AOP框架中,CGLib被用来创建代理对象,实现在方法执行前后的拦截器逻辑,...

    cglib代理资料类,静态代理动态代理

    以上就是关于静态代理、动态代理(JDK)和CGlib代理的基本介绍。它们在Java开发中都有广泛的应用,尤其是在AOP(面向切面编程)和框架设计中,如Spring AOP就使用了这两种代理技术。了解并熟练掌握这些代理机制,...

    cglibJava字节码生成库

    通过这个库,开发者无需手动编写复杂的字节码,而是可以通过简单的API接口来创建新的类或者增强已有的类。这极大地提高了开发效率和代码的可读性,同时降低了出错的可能性。 【详细知识点】: 1. **字节码基础**:...

    常用的jar包简单介绍

    3. **cglib-nodep-2.1_3.jar**: CGLIB是一个代码生成库,主要用于创建代理对象,特别是在Spring AOP中,它可以动态生成子类来实现对目标类的方法拦截。 4. **commons-beanutils.jar**: 提供了访问JavaBeans组件属性...

    JDBC数据库连接池的简单实现.rar

    这里我们以Druid为例,介绍其简单实现。 1. 添加依赖:在项目中引入Druid的Maven或Gradle依赖。例如,如果是Maven项目,可以在pom.xml中添加如下依赖: ```xml &lt;groupId&gt;com.alibaba&lt;/groupId&gt; &lt;artifactId&gt;...

    spring动态代理类的示范小版本,很简单的例子

    下面将详细介绍这两种动态代理机制。 1. JDK动态代理: JDK动态代理基于Java的接口实现。如果我们的目标对象实现了至少一个接口,那么Spring会为我们创建一个代理类,该类实现了相同的接口,并在调用接口方法时...

    简单spring aop 例子

    本示例将简要介绍如何在Spring应用中实现AOP,通过实际的代码示例帮助理解其工作原理。 首先,我们要理解AOP的核心概念。AOP是一种编程范式,它允许开发者定义“切面”(Aspects),这些切面封装了特定的关注点,如...

    jar包介绍大全

    Commons Digester 提供了一个简单易用的框架来解析XML文档并映射到Java对象。对于需要处理XML数据的应用程序而言,它极大地简化了开发过程。 #### Commons Lang (commons-lang.jar) Commons Lang 是一个实用工具库...

    hibernate3 最简单实现项目

    本项目基于Hibernate3,将介绍如何实现最简单的查询功能,并且提供了必要的jar包以供使用。Hibernate3是Hibernate的第三个主要版本,它在性能和功能上都有所提升,同时也保持了与前一版本的良好兼容性。 首先,理解...

    动态代理实现文件.....

    这里我们将深入探讨Java中的两种主要动态代理实现:JDK动态代理和CGLIB动态代理,以及静态代理作为基础概念的介绍。 首先,我们来看静态代理。静态代理是代理模式的一种实现方式,它要求我们为每个目标接口创建一个...

    简单Spring框架模拟器--Demo

    接着,“tiny-spring-step-2-abstract-beanfactory-and-do-bean-initilizing-in-it.zip”进一步深入,介绍了AbstractBeanFactory和Bean的初始化过程。在这个阶段,你将学习到BeanFactory如何解析XML配置,创建Bean...

    Spring AOP源码分析.mmap

    有关于Spring,我们最常用的两个功能就是IOC和AOP,前几篇文章从源码级别介绍了Spring容器如何为我们生成bean及bean之间的依赖关系 下面我们接着来看AOP的源码实现。 有关于AOP,我们在面试中也被无数次问到...

    spring辅助资源包

    下面将详细介绍这些资源包以及它们在Spring框架中的作用。 1. **asm-all-2.2.2.jar**: 这个jar包包含了ASM库的所有组件,ASM是一个Java字节码操控和分析框架,用于动态生成类或者增强已有类的功能。Spring框架在...

    简单好懂的几个设计模式

    以上就是几个简单易懂的设计模式介绍,理解并熟练运用这些模式可以提升代码的可读性、可维护性和复用性。在实际开发中,根据项目需求和场景选择合适的设计模式,可以有效地提高软件的质量和效率。通过不断地学习和...

    java 三大代理模式及其实现

    这三种代理模式各有其特点和应用场景,下面将详细介绍它们的工作原理和实现方式。 ### 静态代理 静态代理是最基础的代理形式,它通过创建一个代理类来间接调用目标对象的方法。在静态代理中,代理类和目标类通常...

    spring aop 详细介绍

    【Spring AOP 详细介绍】 Spring AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的一个重要组成部分,它提供了在不修改源代码的情况下,对应用程序进行功能增强的能力。AOP的核心概念包括Advice...

    proxool连接池所需的jar包

    - **简单易用**:集成到应用中非常简单,只需要添加相应的jar包,并进行简单的配置即可。 **3. jar包介绍** - **proxool-0.9.1.jar**:这是Proxool连接池的核心库,包含了所有必要的类和方法,用于创建、管理和维护...

    高级Java人才培训专家-spring高级49讲

    - **统一jdk和cglib**:介绍Spring如何统一管理和使用JDK和CGLIB代理。 - **切点匹配**:讲解切点表达式的定义及匹配规则。 - **@Aspect与Advisor**:解释Spring AOP中的@Aspect注解和Advisor的作用。 - **静态通知*...

Global site tag (gtag.js) - Google Analytics