`
xm_king
  • 浏览: 392756 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
Group-logo
Spring技术内幕读书笔...
浏览量:15383
社区版块
存档分类
最新评论

Spring AOP 学习笔记-Springle 一代

阅读更多

Spring AOP 一代

在我们详细讨论 Spring AOP 实现的细节之前,我们先给出一个简单的实例为 Spring AOP 的讨论开个头:

我们先编写一个简单输出“ World ”的类,如下所示:

public class MessageWriter 
    public void writeMessage(){
       System.out.print("world");
    }
}

这个 MessageWriter 再简单不过了,它只有一个用以打印“ World ”到标准输出的方法。我们想通知这个类,让它的 writeMessage() 方法实际上输出“ Hello World !”。

为了达到这个目的,我们需要在这个方法体之前执行一段代码来输出“ Hello ”,并在这个方法体之后执行一段代码来输出“!”。用 AOP 术语来说,我们需要一个包围通知 (Around Advice) ,也就是一个包围连接点的通知。在这个实例中,连接点就是对 writeMessage() 方法的调用。下面是这个包围通知的实现:

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/*
 * 实现包围通知
 */
public class MessageDecorator implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
       System.out.print("Hello");
       Object retval=invocation.proceed();
       System.out.print("!");
       return retval;
    }
}

MethodInterceptor 接口是对方法调用连接点实现包围通知的 AOP 联盟标准接口。 MethodInvocation 对象代表当前被通知的方法调用,我们使用这个类来控制具体什么时候进行方法调用。因为我们用的是包围通知,所以我们能够在方法调用之前进行一些操作,还可以在方法调用之后而返回之前执行另外一些操作。

这个实例的最后一步就是将 MessageDecorator 通知织入代码中。为了做到这一步,我们首先建立一个 MessageWriter 对象,即目标对象。然后创建一个代理,并让代理工厂 (ProxyFactory) 织入 MessageDecorator 通知,具体过程代码如下:

import org.springframework.aop.framework.ProxyFactory;
public class HelloWorldWeaver {
    public static void main(String[] args) {
       //目标对象
       MessageWriter target=new MessageWriter();
       //代理工厂类
       ProxyFactory pf=new ProxyFactory();
       //将MessageDecorator通知传给ProxyFactory
       pf.addAdvice(new MessageDecorator());
       //设定织入的目标对象
       pf.setTarget(target);
       //创建一个目标对象的代理
       MessageWriter proxy=(MessageWriter) pf.getProxy();
       target.writeMessage();
       System.out.println();
       proxy.writeMessage();
    }
}

结果如下:

world
Helloworld!

可以看到,在原始对象上调用 writeMessage() 方法只是简单的输出,并没有什么新内容被打印到标准输出。然而,调用代理会执行 MessageDecorator 中的代码,从而生成我们所需要的输出。

从这个例子可以看出, 被通知的类不会与 Spring 或者 AOP 联盟之间并没有产生任何依赖关系。 Spring AOP 的优美之处,事实上也是所有 AOP 的优美之处,就在于我们几乎可以通知任何类,即便在通知这个类的时候并没有考虑 AOP 。唯一的限制,至少在 Spring AOP 中的唯一限制,是我们不能通知 final 类,因为 final 类不能被扩展,我们无法生产它的代理。

Spring AOP架构

Spring AOP 架构的核心是建立在代理上的,当我们建立被通知类的实例时,我们必须使用 ProxyFactory 类加入我们需要织入该类的所有通知。然后为该类的一个对象创建代理。使用 ProxyFactory 创建 AOP 代理是一个完全编程式的做法。大部分情况下,我们不需要在应用中直接这么做,而可以理解 ProxyFactoryBean 类来声明式创建代理。理解代理是如何生成的对于 Spring AOP 是非常重要的。

Spring AOP 内部的两种代理方法: JDK 动态代理和 CGLIB 代理。老版本的 Spring 中两种代理没有什么明显区别,所以我们只在需要代理类而非代理接口时,或者显式声明适用于 CGLIB 代理时才会使用后者,从 Spring1.1 开始, CGLIB 的性能通常会明显好过 JDK 动态代理,尤其是反射机制性能很差的 1.3 版的 JAVA 虚拟机上。理解代理的意义以及它在 Spring 内是怎样被使用的,是提高我们性能的关键。

ProxyFactory类

ProxyFactory 类控制这 Spring AOP 中的织入和创建代理的过程,在真正创建代理之前,我们必须指定被通知对象或者说目标对象。之前我们看到,可以通过 setTarget() 方法来完成这个步骤。查看 Spring 的源码,我们可以看到 ProxyFactory 内部将生成代理对象的过程转交给一个 DefaultAopProxyFactory 对象来完成。后者又根据程序中的设置将其转交给一个 Cglib2AopProxy 或者 JdkDynamicAopProxy 来完成。稍后,我会详细介绍代理的生成过程。

通过 ProxyFactory 类,我们可以控制哪些方面需要被织入到代理中去。前面我们提到过,我们只能在被通知代码中织入方面,也就是一个通知和一个连接点的结合。然而,有时候我们希望在目标类中的所有方法被调用时都执行通知,而不只是一部分方法被访问。在这种情况下, ProxyFactory 提供了 addAdvice() 方法。 查看 Spring 的源码, 该方法内部会将我们提供的通知包装在一个 DefaultPointcutAdvisor 对象内,是 PointcutAdvisor 的标准实现。将其配置为包含所有默认方法调用的切入点。如果我们想对创建的 Advisor 有更多的控制,或者要向代理中添加一个引入,可以自行创建创建 Advisor 并使用 ProxyFactory addAdvisor() 方法。

你可以使用 ProxyFactory 创建许多不同的代理,各个代理的方面都可以不同。为了方便使用, ProxyFactory 类有 removeAdvice() removeAdvisor() 方法,通过这些方法我们可以删除之前加入 ProxyFactory 的任何通知或通知者。

Spring中创建通知

       Advice

Advices 实现了 Aspect 的真正逻辑,具体来说是在 JAVA 中就是一个类或更细粒度的设计成了一个方法 ( 由一个类来集中管理许多 Advice) 。由于织入至 Target 的时机不同, Spring 提供了几种不同的 Advice ,像 Before Advice After Advice Around Advice Throw Advice

Before Advice 会在目标对象的方法执行之前被调用,在 Spring2.0 之前,也就是传统的 Spring 中需要实现 org.springframework.aop.MethodBeforeAdvice 接口来实现 Before Advice 的逻辑。

public interface MethodBeforeAdvice extends BeforeAdvice {
    void before(Method method, Object[] args, Object target) throws Throwable;
}

MethodBeforeAdvice 继承自 BeforeAdvice ,而 BeforeAdvice 又继承自 Advice 接口,后两者都是标签接口 (Tag Interface) ,只能用作标示而无法定义任何方法, MethodBeforeAdvice Before() 方法会在目标对象 (Target) 所指定的方法执行之前被执行。在 before() 方法执行完毕之后,除非丢出异常,否则目标对象上的方法就会被执行。

下面以实例来说明如何使用 Before Advice ,首先定义目标对象必须实现的接口:

public class IHelloImpl implements IHello{
    public void hello1(String name) {
       System.out.println("hello1,"+name);
    }
    public void hello2(String name) {
       System.out.println("hello2,"+name);
    }
}

在不对 IHelloImpl 进行修改的情况下,需要在 hello() 方法执行之前,可以记录一些消息。可以实现 MethodBeforeAdvice 接口,例如:

public class LogBeforeAdvice  implements MethodBeforeAdvice{
         public void before(Method method, Object[] args, Object target)
                            throws Throwable {
       System.out.println(method.getName()+",start.............LogBeforeAdvice");
         }
}

      LogBeforeAdvice 类被设计为一个独立的服务,可以提供给需要的对象,接着只要在定义文件中如下定义:

<bean id="IHello" class="com.edu.cug.IHelloImpl"></bean>
<bean id="logBeforeAdvice" class="com.edu.cug.advice.LogBeforeAdvice">
<bean id="IHelloProxy"
       class="org.springframework.aop.framework.ProxyFactoryBean">
       <property name="target" ref="IHello"></property>
       <property name="proxyInterfaces" value="com.edu.cug.IHello"/>
       <property name="interceptorNames">
           <list>
                <value>logBeforeAdvice</value>
           </list>
       </property>
</bean>

注意到除了建立 Advice Target 的对象实例之外,你还使用了 org.springframework.aop.framework.ProxyFactoryBean ,这个类会被 BeanFactory 或是 ApplicationContext 用来建立代理对象,这个 ProxyFactoryBean 是一个 FactoryBean ,对 Factory 这种 Spring 应用中经常出项的 Bean 的形式,读者一定不会感到陌生,对于 FactoryBean 的工作原理,请读者自己查看 IOC 容器的相关知识。

ProxyFactoryBean 中,通过 interceptorNames 属性来配置已经定义好的通知器 Advisor 。虽然这里的名字叫做 interceptNames ,但值得注意的是,实际上却是供 AOP 应用配置通知器的地方。在不指定目标方法时, Advice 会织入至接口上的所有方法。在 ProxyFactoryBean 中,需要为 Target 目标对象生成 Proxy 代理对象,从而为 AOP 横切面编织做好准备工作。这些具体的代理对象生成工作,是通过 JDK 的动态代理或 CGLIB 来完成的。

下面编写程序测试 Before Advice 的运行:

public class AopTest {
    public static void main(String[] args) {
       BeanFactory factory = new ClassPathXmlApplicationContext(
             "applicationContext.xml");
       IHello bean = (IHello) factory.getBean("IHelloProxy");
       bean.hello1("AOP1");
       bean.hello2("AOP2");
    }
}

来看一下执行结果:

hello1,start.............LogBeforeAdvice
hello1,AOP1
hello2,start.............LogBeforeAdvice
hello2,AOP2

下面将使用编程式的方式来测试 Before Advice 的运行:

public class AopTest {
    public static void main(String[] args) {
       IHello hello=new IHelloImpl();
       ProxyFactory pf=new ProxyFactory();
       Advice advice=new LogBeforeAdvice();
       pf.addAdvice(advice);
       pf.setTarget(hello);
       IHello proxy=(IHello) pf.getProxy();
       hello.hello1("AOP1");
       System.out.println("==================");
       proxy.hello1("AOP1");
    }
}

运行结果:

hello1,AOP1
==================
hello1,start.............LogBeforeAdvice
hello1,AOP1

 

进入到 Spring 的源码中进行分析,首先看一下声明式的 Spring AOP 编程,在 ProxyFactoryBean 中,它的 AOP 实现需要依赖 JDK 或者 CGLIB 提供的 Proxy 特性。从 FactoryBean 中取得对象,是用 getObject() 方法作为入口完成的。

getObject() 方法中, Spring 使用这个 AopProxy 接口把 AOP 代理对象的实现与框架的其他部分有效地分离。 AopProxy 接口有两个子类实现,一个时 cglib2AopProxy ,另一个是 JdkDynamicProxy

创建 AopProxy 的过程是在 AopProxyFactory 中进行的,在 Spring 中, AopProxyFactory 使用的是 DefaultAopProxyFactory 。这个被使用的 DefaultAopProxyFactory ,作为 AopProxy 的创建工厂对象。有了这个 AopProxyFactory 对象以后,我们再到 DefaultAopProxyFactory 中看一下 AopProxy 是怎样生成的。

关于 AopProxy 代理对象的生产,需要考虑使用哪种生成方法,如果目标对象是接口类,那么适合使用 JDK 来生成代理对象,否则 Spring 会使用 CGLIB 来生成目标对象的代理对象。为了满足不同的代理对象生成的要求, DefaultAopProxyFactory 作为 AopProxy 的生产工厂,可以根据不同的需要生成两种 AopProxy 对象。

这样就分别得到了 JdkDynamicAopProxy 对象和 Cglib2AopProxy 对象,剩下的问题就是分别在两个产生代理对象的类中生成除代理对象。

在编程式的 Spring AOP ProxyFactory getProxy() 方法,归根结底还是赚到了 createAopProxy().getProxy() 之上,这一部分是在 ProxyCreatorSupport. createAopProxy() 中实现的,有兴趣的读者可以自行查看 Spring 的源码。

从这里看出, Spring AOP 是紧紧地围绕在 IOC 这个 Spring 的核心概念之上的。我们可以从 Spring IOC 容器中取得我们的代理对象,可以通过编程式的来取得代理对象。在实际中,用编程式的机会很少,这里,只是说明问题。

After Advice 会在目标方法执行之后被调用,在传统的 Spring 当中,应当实现 org.springframework.aop.AfterReturningAdvice 接口来实现 After Advice 的逻辑。

Around Advice 会在指定的程序前后均执行相关的服务,在传统的 Spring 当中,编写环绕通知,应当实现 org.aopalliance.intercept.MethodInterceptor ,这个接口是 AOP Alliance 规范的接口。

Throw Advice( 异常通知 ) 在程序发生异常的时候执行相关的服务,在传统的 Spring 当中,,异常通知类应 当实现 org.springframework.aop. ThrowsAdvice

Pointcut、Advisor

在上一节中,讲解了 Spring 4种 通知的实现,然而这四种通知都是直接织入到代理的接口执行前后的。事实上还可以定义更细粒度的织入时机。 Pointcut 定义了感兴趣的 JoinPoint(Advice 织入时机 ) 。在 Spring 中,使用 PointcutAdvisor 提供 Pointcut 实例,具体结合 Advice Spring 内建的 Pointcut 都有对应的 PointcutAdvisor

在最开始我们使用编程式 Spring AOP 中,我们调用 ProxyFactory.addAdvice() 方法为代理设定通知。该方法会在后台委托给 addAdvisor() 方法。而后者会创建一个 DefaultPointcutAdvisor 实例并将切入点设为所有方法的调用,目标的所有方法都能被通知到了。在 DefaultPointcutAdvisor Pointcut 设置为 TruePointcut ,对任何的方法匹配都返回 true 的结果。

NameMatchMethodPointcutAdvisor

Pointcut 定义了 Joinpoint ,在 Spring 中使用 PointcutAdvisor 来提供 Pointcut 、结合 Advice PointcutAdvisor Advisor 的子接口, Advisor 定义如下:

public interface Advisor {
    Advice getAdvice();
    boolean isPerInstance();
}

PointcutAdvisor 接口在 Spring 中的定义如下:

public interface PointcutAdvisor extends Advisor {
    Pointcut getPointcut();
}

Spring 中内建的 Pointcut 都有对应的 PointcutAdvisor ,在这里介绍一下,如何使用 Spring org.springframework.aop.support.NameMatchMethodPointcutAdvisor ,这是最基本的 PointcutAdvisor ,用以提供 Spring 的静态的 Pointcut 实例,可以使用正则表达式指定 Advice 应用目标上的方法名称。

下面举个例子说明, Spring 配置如今如下:

<bean id="logBeforeAdvisor"
class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
       <property name="mappedName" value="hello*"></property>
       <property name="advice" ref="logBeforeAdvice"></property>  
</bean>
<bean id="IHelloProxy"
       class="org.springframework.aop.framework.ProxyFactoryBean">
       <property name="target" ref="IHello"></property>
       <property name="proxyInterfaces" value="com.edu.cug.IHello"/>
       <property name="interceptorNames">
               <list>
                   <value>logBeforeAdvisor</value>
               </list>
       </property>
</bean>

       NameMatchMethodPointcutAdvisor mappedName 属性上,由于制定了 ”hello*” ,所以执行 hello1() hello2() 方法时,就会织入 logBeforeAdvice 通知。编写一下程序来进行测试。

public class AopTest {
    public static void main(String[] args) {
       BeanFactory factory = new ClassPathXmlApplicationContext(
              "applicationContext.xml");
       IHello bean = (IHello) factory.getBean("IHelloProxy");
       bean.hello1("AOP1");
       bean.hello2("AOP2");
    }
}

执行结果如下所示:

hello1,start.............LogBeforeAdvice
hello1,AOP1
hello2,start.............LogBeforeAdvice
hello2,AOP2

RegexpMethodPointcutAdvisor
      Spring除了使用前面的NameMatchMethodPointcutAdvisor可以指定通知的方法外,还提供了正则表达式切入点的表示方法:org.springframework.aop.support.NameMatchMethodPointcutAdvisor。Spring还定义了其他的一些PointcutAdvisor,请读者自行查阅其他的资料。
IntroductionInterceptor(引入)
       对于之前介绍过的Before Advice、After Advice、Around Advice、Throw Advice,从用户的角度来看,它们”影响了目标对象上的某些方法的执行”。 Introduction是个特别的Advice,从用户的角度来看,它“影响了目标对象的定义,直接增加了目标对象的职责(具体来说就是增加了可操作的方法)”,例如让某个定义好的对象,在不修改对象的类文件的情况下,却可以增加一些额外的操作方法到对象之上。
      IntroductionInterceptor继承了MethodInterceptor,DynamicIntroductionAdvice接口,其中implementsInterface()返回true,表明目前的IntroductionInterceptor实现了规定的接口(也就是要额外增加行为的接口),此时要使用invoke执行接口上的方法,让目标对象执行额外的行为。
      假如在不希望修改源文件的情况下,为IHello增加一些可操作的方法,在Spring中,可以通过实现IntroductionInterceptor接口来完成上面的任务,首先为doOther()方法建立接口:

public interface IOther {
    public void doOther();
}

       接着定义一个OtherIntroduction类同时实现IntroductionInterceptor接口与IOther接口。例如:

public class OtherIntroduction implements IOther, IntroductionInterceptor {
    // 是否实现自IOther接口
    @SuppressWarnings("unchecked")
    public boolean implementsInterface(Class clazz) {
        return clazz.isAssignableFrom(IOther.class);
    }
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        if (implementsInterface(methodInvocation.getMethod()
                .getDeclaringClass())) {
            // 执行额外加入的行为
            return methodInvocation.getMethod().invoke(this,
                    methodInvocation.getArguments());
        } else {
            return methodInvocation.proceed();
        }
    }
    public void doOther() {
        // TODO Auto-generated method stub
        System.out.println("增加的职责!");
    }
}

       接着要在Bean定义文件中将Introduction织入至IHello对象之上,使用org.springframework.aop.support.DefaultIntroductionAdvisor就可以了。

<bean id="otherIntroduction" class="com.edu.cug.advice.OtherIntroduction" />
<bean id="otherAdvisor"
      class="org.springframework.aop.support.DefaultIntroductionAdvisor">
        <constructor-arg ref="otherIntroduction" />
        <constructor-arg value="com.edu.cug.advice.IOther" />
</bean>
<bean id="IHelloProxy"
        class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="IHello"></property>
        <property name="proxyInterfaces" value="com.edu.cug.IHello"/>
        <property name="interceptorNames">
            <list>
                    <value>otherAdvisor</value>
            </list>
        </property>
</bean>

      DefaultIntroductionAdvisor在构造时,需要给它IntroductionInterceptor的实例,以及所要代理额外行为的接口,现在,来编写一个简单的程序测试:

public class AopTest {
    public static void main(String[] args) {
       
        BeanFactory factory = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        IHello bean = (IHello) factory.getBean("IHelloProxy");
        bean.hello1("AOP1");
        bean.hello2("AOP2");
        ((IOther) bean).doOther();
    }
}

    运行结果如下:

hello1,AOP1
hello2,AOP2
增加的职责!

      对于IHello所参考的对象来说,通过Spring AOP的Introduction机制,现在IHello对象多了doOther()方法可以操作。
这个就是传统的Spring的支持,讲解的较为粗略,只是起到抛砖引玉的作用,详细的应用请读者查看其他的资料。

 

分享到:
评论

相关推荐

    Spring5 框架 ---- AOP ---- 代码

    Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 框架 ---- AOP ---- 代码 Spring5 ...

    spring-aop-5.3.10-API文档-中文版.zip

    赠送jar包:spring-aop-5.3.10.jar; 赠送原API文档:spring-aop-5.3.10-javadoc.jar; 赠送源代码:spring-aop-5.3.10-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.10.pom; 包含翻译后的API文档:spring...

    spring-aop.jar各个版本

    spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...

    开发工具 spring-aop-4.3.6.RELEASE

    开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE开发工具 spring-aop-4.3.6.RELEASE...

    spring-aop-5.3.12-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.3.12.jar; 赠送原API文档:spring-aop-5.3.12-javadoc.jar; 赠送源代码:spring-aop-5.3.12-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.12.pom; 包含翻译后的API文档:spring...

    spring-aop-5.3.15-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.3.15.jar; 赠送原API文档:spring-aop-5.3.15-javadoc.jar; 赠送源代码:spring-aop-5.3.15-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.15.pom; 包含翻译后的API文档:spring...

    spring-aop-5.3.15-API文档-中文版.zip

    赠送jar包:spring-aop-5.3.15.jar; 赠送原API文档:spring-aop-5.3.15-javadoc.jar; 赠送源代码:spring-aop-5.3.15-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.15.pom; 包含翻译后的API文档:spring...

    spring-aop-5.3.7-API文档-中文版.zip

    赠送jar包:spring-aop-5.3.7.jar; 赠送原API文档:spring-aop-5.3.7-javadoc.jar; 赠送源代码:spring-aop-5.3.7-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.7.pom; 包含翻译后的API文档:spring-aop...

    spring-aop-5.2.0.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-5.2.0.RELEASE.jar; 赠送原API文档:spring-aop-5.2.0.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.2.0.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.2.0.RELEASE.pom;...

    spring-aop-5.3.7-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.3.7.jar; 赠送原API文档:spring-aop-5.3.7-javadoc.jar; 赠送源代码:spring-aop-5.3.7-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.3.7.pom; 包含翻译后的API文档:spring-aop...

    spring-aop-5.3.10-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.3.10.jar;赠送原API文档:spring-aop-5.3.10-javadoc.jar;赠送源代码:spring-aop-5.3.10-sources.jar;赠送Maven依赖信息文件:spring-aop-5.3.10.pom;包含翻译后的API文档:spring-aop...

    aopalliance-1.0.jar,org.springframework.aop-3.0.0.RELEASE.jar

    aopalliance-1.0.jar,org.springframework.aop-3.0.0.RELEASE.jar,org.springframework.jdbc-3.0.0.RELEASEorg.springframework.beans-3.0.0.RELEASE.jar等

    spring-aop-5.0.8.RELEASE-API文档-中英对照版.zip

    赠送jar包:spring-aop-5.0.8.RELEASE.jar; 赠送原API文档:spring-aop-5.0.8.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.8.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.8.RELEASE.pom;...

    小马哥讲 Spring AOP 编程思想 - API 线索图.pdf

    小马哥讲 Spring AOP 编程思想 - API 线索图.pdf

    org.springframework.aop-sources-3.0.5.release.jar

    org.springframework.aop-sources-3.0.5.release.jar

    spring-aop-5.0.10.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-5.0.10.RELEASE.jar; 赠送原API文档:spring-aop-5.0.10.RELEASE-javadoc.jar; 赠送源代码:spring-aop-5.0.10.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-5.0.10.RELEASE....

    spring ioc aop mvc boot-学习笔记.docx

    自己学习spring课程的笔记。笔记都是根据尚硅谷的课程(spring ioc,spring aop,spring mvc,spring boot等)写的。 主要内容:spring ioc,spring aop,spring mvc,spring boot

    spring-aop-4.2.2.RELEASE-API文档-中文版.zip

    赠送jar包:spring-aop-4.2.2.RELEASE.jar; 赠送原API文档:spring-aop-4.2.2.RELEASE-javadoc.jar; 赠送源代码:spring-aop-4.2.2.RELEASE-sources.jar; 赠送Maven依赖信息文件:spring-aop-4.2.2.RELEASE.pom;...

    spring aop 学习笔记

    NULL 博文链接:https://microjava.iteye.com/blog/525796

    spring-aop-annotation-log-all

    spring-aop-4.0.4.RELEASE.jar com.springsource.net.sf.cglib-2.2.0.jar com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar spring-aspects-4.1.2.RELEASE.jar ...

Global site tag (gtag.js) - Google Analytics