国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Learn Spring - Spring AOP

kgbook / 2559人閱讀

摘要:下例表示方法入參為的方法匹配該切點,并將和兩個參數綁定到切面方法的入參中綁定代理對象使用或可以綁定被代理對象的實例。

1. 術語

連接點(JointPoint):代碼中具有邊界性質特定點;Spring僅支持方法的連接點,包含方法和方位兩方面信息

切點(Pointcut):定位到某個方法

增強(Advice):織入到目標連接點上的代碼

目標對象(Target):增強邏輯的目標織入類

引介(Introduction):特殊的增強,為類添加一些屬性和方法

織入(Weaving):將增強添加到目標連接點上的過程:編譯期織入、類裝載期織入、動態代理織入(Spring的方案)

代理(Proxy):被AOP織入增強后的結果類

切面(Aspect):切點+增強

2. 動態代理的兩種實現:JDK和CGLib

JDK動態代理動態創建一個符合某一接口的實力,生成目標類的代理對象,缺點是需要提供接口;方法必須是publicpublic final

CGLib采用底層的字節碼技術,在子類中對父類的方法進行攔截,織入橫切邏輯;不能為finalprivate方法代理

樣例

package test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class ProxyTest {

    public static void main(String[] args) {
        ServiceImpl jdkTarget = new ServiceImpl();
        ProxyHandler handler = new ProxyHandler(jdkTarget);
        Service jdkProxy = (Service)Proxy.newProxyInstance(
            jdkTarget.getClass().getClassLoader(),
            jdkTarget.getClass().getInterfaces(),
            handler);
        jdkProxy.process("jdk proxy");

        System.out.println();

        CglibProxy cglibProxy = new CglibProxy();
        ServiceImpl cglibTarget = (ServiceImpl)cglibProxy.getProxy(ServiceImpl.class);
        cglibTarget.process("cglib proxy");
    }

    public interface Service {
        public void process(String arg);
    }

    public static class ServiceImpl implements Service {
        @Override
        public void process(String arg) {
            System.out.println("do something with " + arg);
        }
    }

    //jdk proxy
    public static class ProxyHandler implements InvocationHandler {
        private Object target;
        public ProxyHandler(Object target) {
            this.target = target;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
            System.out.println("before process jdk proxy");
            Object obj = method.invoke(target, args);
            System.out.println("after process jdk proxy");
            return obj;
        }
    }

    //cglib proxy
    public static class CglibProxy implements MethodInterceptor {
        private Enhancer enhancer = new Enhancer();
        public Object getProxy(Class clazz) {
            enhancer.setSuperclass(clazz);
            enhancer.setCallback(this);
            return enhancer.create();
        }

        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("before process cglib proxy");
            Object result = proxy.invokeSuper(obj, args);
            System.out.println("after process cglib proxy");
            return result;
        }
    }
}

結果

before process jdk proxy
do something with jdk proxy
after process jdk proxy

before process cglib proxy
do something with cglib proxy
after process cglib proxy

性能:CGLib所創建的動態代理對象性能比JDK方式高(約10倍),但CGLib在創建代理對象時所花費的時間比JDK方式多(約8倍);CGLib適合Spring里singleton模式的bean管理

3. ProxyFactory

Spring定義了org.springframework.aop.framework.AopProxy接口及Cglib2AopProxyJdkDynamicAopProxy兩個final實現類

如果通過ProxyFactorysetInterfaces(Class[] interfaces)指定針對接口代理,則使用JdkDynamicAopProxy;如果使用setOptimize(true),使用Cglib2AopProxy

ProxyFacotry通過addAdvice(Advice)形成增強鏈

4. 增強類型 4.1 前置增強

接口:org.springframework.aop.BeforeAdvice

樣例

package com.aop;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

public class BeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method arg0, Object[] arg1, Object arg2)
        throws Throwable {
        String arg = (String)arg1[0];
        System.out.println("before advice " + arg);
    }
}
4.2 后置增強

接口:org.springframework.aop.AfterReturninigAdvice

樣例

package com.aop;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;

public class AfterAdvice implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        String arg = (String)args[0];
        System.out.println("after advice " + arg);
    }
}
4.3 環繞增強

接口:org.aopalliance.intercept.MethodInterceptor

樣例

package com.aop;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class AroundAdvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object[] args = invocation.getArguments();
        String arg = (String)args[0];
        System.out.println("around advice: before " + arg);
        Object obj = invocation.proceed();
        System.out.println("around advice: after " + arg);
        return obj;
    }
}
4.4 異常拋出增強

接口:org.springframework.aop.ThrowsAdvice

樣例

package com.aop;
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;

public class ExceptionAdvice implements ThrowsAdvice {
    public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
        throws Throwable {
        System.out.println("------");
        System.out.println("throws exception, method=" + method.getName());
        System.out.println("throws exception, message=" + ex.getMessage());
    }
}
4.5 測試
4.5.1 基于代碼的測試

TestAopAdvice

package com.aop;
import org.springframework.aop.ThrowsAdvice;
import org.springframework.aop.framework.ProxyFactory;

public class TestAopAdvice {
    public static void main(String[] args) {
        AopExample example = new AopExample();
        BeforeAdvice beforeAdvice = new BeforeAdvice();
        AfterAdvice afterAdvice = new AfterAdvice();
        AroundAdvice aroundAdvice = new AroundAdvice();
        ThrowsAdvice throwsAdvice = new ExceptionAdvice();

        ProxyFactory pf = new ProxyFactory();
        pf.setTarget(example);
        pf.addAdvice(beforeAdvice);
        pf.addAdvice(afterAdvice);
        pf.addAdvice(aroundAdvice);
        pf.addAdvice(throwsAdvice);
        AopExample proxy = (AopExample)pf.getProxy();

        proxy.handle("blabla");
        System.out.println();

        try{
            proxy.throwExp("blabla");
        } catch(Exception e) {
        }
    }
}

輸出

before advice blabla
around advice: before blabla
aop example blabla
around advice: after blabla
after advice blabla

before advice blabla
around advice: before blabla
----after throwing----
throws exception, method=throwExp
throws exception, message=try throws advice
4.5.2 基于Spring配置的測試

springAop.xml




    
    
    
    
    
    

TestAopAdvice2

package com.aop;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAopAdvice2 {
    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("/springAop.xml");
        AopExample aopExample = (AopExample)ctx.getBean("aopTest");
        aopExample.handle("blabla");
        System.out.println();
        try{
            aopExample.throwExp("blabla");
        } catch(Exception e) {
        }
        ctx.close();
    }
}

輸出

二月 09, 2017 9:54:11 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@69d0a921: startup date [Thu Feb 09 21:54:11 CST 2017]; root of context hierarchy
二月 09, 2017 9:54:11 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [springAop.xml]
before advice blabla
around advice: before blabla
aop example blabla
around advice: after blabla
after advice blabla

before advice blabla
around advice: before blabla
----after throwing----
throws exception, method=throwExp
throws exception, message=try throws advice
二月 09, 2017 9:54:11 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@69d0a921: startup date [Thu Feb 09 21:54:11 CST 2017]; root of context hierarchy
4.6 引介增強

接口:org.springframework.aop.IntroductionInterceptor

4.6.1 基于Spring配置的測試代碼

IntroductionAdvice

package com.aop;

public interface IntroductionAdvice {
    public void setIntroductionActive(boolean active);
}

ConfigurableIntroduction

package com.aop;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;

public class ConfigurableIntroduction extends DelegatingIntroductionInterceptor implements IntroductionAdvice {

    private ThreadLocal map = new ThreadLocal();

    @Override
    public void setIntroductionActive(boolean active) {
        map.set(active);
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object obj = null;
        if(map.get() != null && map.get()) {
            System.out.println("before monitor operation");
            obj = super.invoke(invocation);
            System.out.println("after monitor operation");
        } else {
            obj = super.invoke(invocation);
        }
        return obj;
    }
}

TestIntroductionAdvice

package com.aop;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestIntroductionAdvice {

    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("/springAop.xml");
        AopExample introductionAop = (AopExample)ctx.getBean("introductionAop");
        introductionAop.handle("introduction advice");
        IntroductionAdvice ci = (IntroductionAdvice)introductionAop;
        ci.setIntroductionActive(true);
        introductionAop.handle("introduction advice");
        ctx.close();
    }
}

springAop.xml添加


輸出

二月 09, 2017 9:56:10 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@69d0a921: startup date [Thu Feb 09 21:56:10 CST 2017]; root of context hierarchy
二月 09, 2017 9:56:10 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [springAop.xml]
aop example introduction advice
----
before monitor operation
aop example introduction advice
after monitor operation
二月 09, 2017 9:56:11 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@69d0a921: startup date [Thu Feb 09 21:56:10 CST 2017]; root of context hierarchy
4.6.2 與其他增強在配置上的區別

須指定引介增強所實現的接口

只能通過為目標類創建子類的方式生成引介增強的代理,因此proxyTargeClass必須為true

5. Spring中的配置

參數說明

target:代理的對象

proxyInterfaces:代理所要實現的接口

interceptorNames:需要織入目標對象的bean列表,這些bean必須是實現了org.aopalliance.intercept.MethodInterceptororg.springframework.aop.Advisor的bean,配置中的順序對應調用的順序

singleton:返回的代理是否為單例,默認為true

optimize:為true時使用CGLib代理

proxyTargetClass:為true時使用CGLib代理,并覆蓋proxyInterfaces設置

6. Java注解

一個例子

package com.aspectj;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;

@Target(ElementType.METHOD) //聲明可以使用該注解的目標類型
@Retention(RetentionPolicy.RUNTIME)//聲明注解的保留期限
public @interface Authority {
    boolean value() default true;//聲明注解成員
}

成員以無入參無拋出異常的方式聲明

可以通過default為成員指定一個默認值

在方法上使用注解:@Authority(value=true)

如果注解只有一個成員,需命名為value(),使用時可以忽略成員名和賦值號(=),如@Authority(true)

注解類擁有多個成員時,如果僅對value成員賦值,可以不適用賦值號;如果同時對多個成員賦值,則必須使用賦值號

注解類可以沒有成員,稱為標識注解

所有注解類隱式繼承于java.lang.annotation.Annotation,注解不允許顯式繼承于其他接口

如果成員是數組類型,可以通過{}賦值

7. 基于AspectJ的AOP 7.1 一個例子

定義切面

package com.aspectj;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class PreAspect {
    @Before("execution(*handle(..))")
    public void before() {
        System.out.println("aspect: before processing");
    }
}

測試

package com.aspectj;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
import com.aop.AopExample;

public class AspectJTest {
    public static void main(String[] args) {
        AspectJProxyFactory factory = new AspectJProxyFactory();
        AopExample example = new AopExample();
        factory.setTarget(example);
        factory.addAspect(PreAspect.class);
        AopExample proxy = factory.getProxy();
        proxy.handle("pre aspect");
    }
}

結果

aspect: before processing
aop example pre aspect
7.2 通過配置使用切面
7.2.1 典型配置

springAspectj.xml




    
    
    
7.2.2 基于Schema的配置

springAspectj.xml




    
    
    

AspectJTest2

package com.aspectj;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.aop.AopExample;

public class AspectJTest2 {
    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("/springAspectj.xml");
        AopExample aopExample = (AopExample)ctx.getBean("aopExample");
        aopExample.handle("blabla");
        ctx.close();
    }
}

輸出

二月 09, 2017 10:13:56 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@69d0a921: startup date [Thu Feb 09 22:13:56 CST 2017]; root of context hierarchy
二月 09, 2017 10:13:56 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [springAspectj.xml]
aspect: before processing
aop example blabla
二月 09, 2017 10:13:57 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@69d0a921: startup date [Thu Feb 09 22:13:56 CST 2017]; root of context hierarchy

通過引入aop命名空間,自動為Spring容器中匹配@AspectJ切面的bean創建代理,完成切面織入,其內部實現仍為AnnotationAwareAspectJAutoProxyCreator

proxy-target-class屬性為false時,采用JDK動態代理;為true時使用CGLib

8. AspectJ語法 8.1 切點表達式函數

分類

類型 說明 舉例
方法切點函數 通過描述目標類方法信息定義連接點 execution()@annotation()
方法入參切點函數 通過描述目標類方法入參的信息定義連接點 args()@args()
目標類切點函數 通過描述目標類類型信息定義連接點 within()target()@within()@target()
代理類切點函數 通過描述目標類的代理類的信息定義連接點 this()

函數說明

函數 入參 說明
execution() 方法匹配模式串 表示滿足某一匹配模式的所有目標類方法連接點,如execution(* handle(..))表示所有目標類中的handle()方法
@annotation() 方法注解類名 表示標注了特定注解的目標方法連接點,如@annotation(com.aspectj.Authority)表示任何標注了@Authority注解的目標類方法
args() 類名 通過判別目標類方法運行時入參對象的類型定義指定連接點,如args(com.data.Car)表示所有有且僅有一個按類型匹配于Car(含子類)入參的方法
@args() 類型注解類名 通過判別目標方法運行時入參對象的類是否標注特定注解來制定連接點,如@args(com.aspectj.Authority)表示任何這樣的一個目標方法:它有一個入參且入參對象的類標注@Authority注解。要使@args()生效,類繼承樹中,標注注解的類類型需要不高于入參類類型
within 類名匹配串 表示特定域下的所有連接點,如within(com.service.*)within(com.service.*Service)within(com.service..*)
target() 類名 假如目標按類型匹配于指定類,則目標類的所有連接點匹配這個切點。如通過target(com.data.Car)定義的切點,CarCar的子類中的所有連接點都匹配該切點,包括子類中擴展的方法
@within() 類型注解類名 假如目標類按類型匹配于某個類A,且類A標注了特定注解,則目標類的所有連接點都匹配于這個切點。如@within(com.aspectj.Authority)定義的切點,假如Car類標注了@Authority注解,則Car以及Car的子類的所有連接點都匹配。@within標注接口類無效
@target() 類型注解類名 目標類標注了特定注解,則目標類(不包括子類)所有連接點都匹配該切點。如通過@target(com.aspectj.Authority)定義的切點,若BMWCar標注了@Authority,則BMWCar所有連接點匹配該切點
this() 類名 代理類按類型匹配于指定類,則被代理的目標類所有連接點匹配切點
8.2 通配符
8.2.1 通配符類型
類型 說明
* 匹配任意字符,但只能匹配上下文中的一個元素
.. 匹配任意字符,可以匹配上下文中的多個元素。表示類時,和*聯合使用;表示入參時多帶帶使用
+ 按類型匹配指定類的所有類(包括實現類和繼承類),必須跟在類名后面
8.2.1 函數按通配符支持分類

支持所有通配符:execution()within()

僅支持+通配符:args()this()target()

不支持通配符:@args@within@target@annotation

8.3 增強類型

@Before:前置增強,相當于BeforeAdvice

@AfterReturning:后置增強,相當于AfterReturningAdvice

@Around:環繞增強,相當于MethodInterceptor

@AfterThrowing:相當于ThrowsAdvice

@After:Final增強,拋出異常或正常退出都會執行的增強

@DeclareParents:引介增強,相當于IntroductionInterceptor

8.4 Execution()

語法:execution(<修飾符模式>? <返回類型模式> <方法名模式> (<參數模式>) <異常模式>?)

8.4.1 通過方法簽名定義切點

execution(pulic * *(..)):匹配目標類的public方法,第一個*代表返回類型,第二個*代表方法名,..代表任意入參

execution(* *To(..)):匹配目標類所有以To結尾的方法,第一個*代表返回類型,*To代表任意以To結尾的方法

8.4.2 通過類定義切點

execution(* com.data.User.*(..)):匹配User接口的所有方法

execution(* com.data.User+.*(..)):匹配User接口的所有方法,包括其實現類中不在User接口中定義的方法

8.4.3 通過類包定義切點

execution(* com.data.*(..)):匹配data包下所有類的所有方法

execution(* com.data.User..*(..)):匹配data包及其子孫包中的所有類的所有方法

execution(* com..*Manager.get*(..)):匹配com包及其子孫包中后綴為Manager的類里以get開頭的方法

8.4.4 通過方法入參定義切點

execution(* get(String, int)):匹配get(String, int)方法

execution(* get(String, *)):匹配名為get且第一個入參類型為String、第二個入參類型任意的方法

execution(* get(String, ..)):匹配名為get且第一個入參為String類型的方法

execution(* get(Object+)):匹配名為get且唯一入參是Object或其子類的方法

8.5 進階
8.5.1 邏輯運算符

&&,或||,非!

8.5.2 切點復合運算

例如:@After("within(com.data.*) && execution(* handle(..))")

8.5.3 命名切點

使用@Pointcut命名切點

使用方法名作為切點的名稱,方法的訪問控制符控制切點的可用性

@Pointcut("within(com.data.*)")
public void inPackage(){} //別名為inPackage
8.5.4 增強織入的順序

如果增強在同一個切面類中聲明,則依照增強在切面類中定義的順序織入

如果增強位于不同的增強類中,且都實現了org.springframework.core.Ordered接口,則由接口方法的順序號決定(順序號小的先織入)

如果增強位于不同的增強類中,且沒有實現org.springframework.core.Ordered接口,織入順序不確定

8.5.5 訪問連接點信息

AspectJ使用org.aspectj.lang.JointPoint接口表示目標類連接點對象。如果是環繞增強時,使用org.aspectj.lang.ProceedingJointPoint表示連接點對象,該類是JointPoint接口的子接口。任何一個增強方法都可以通過將第一個入參聲明為JointPoint訪問到連接點上下文的信息

8.5.6 綁定連接點方法入參

args()用于綁定連接點方法的入參,@annotation()用于綁定連接點方法的注解對象,@args()用于綁定連接點方法的入參注解。下例表示方法入參為(String, int, ..)的方法匹配該切點,并將nameage兩個參數綁定到切面方法的入參中

@Before("args(name, age, ..)")
public void bindJointPointValues(String name, int age) {
    //do something
}
8.5.7 綁定代理對象

使用this()target()可以綁定被代理對象的實例。下例表示代理對象為User類的所有方法匹配該切點,且代理對象綁定到user入參中

@Before("this(user)")
public void bindProxy(User user) {
    //do something
}
8.5.8 綁定類注解對象

@within()@target()函數可以將目標類的注解對象綁定到增強方法中

@Before("@within(a)")
public void bindAnnotation(Authority a) {
    //do something
}
8.5.9 綁定返回值

通過returning綁定連接點方法的返回值

@AfterReturning(value="target(com.data.Car)", returning="rvl")
public void bindReturningValue(int rvl) {
    //do something
}

rvl的類型必須和連接點方法的返回值類型匹配

8.5.10 綁定拋出的異常

使用AfterThrowing注解的throwing成員綁定

@AfterThrowing(value="target(com.data.Car)", throwing="iae")
public void bindException(IllegalArgumentException iae) {
    //do something
}

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66593.html

相關文章

  • Learn Spring - Spring DAO

    摘要:概念的異常體系建立在運行期異常的基礎上,封裝了源異常數據訪問流程準備資源啟動事務在事務中執行具體數據訪問操作提交回滾事務關閉資源,處理異常將相同的數據訪問流程固化到模板類中,把數據訪問中固定和變化的部分分開,同時保證模板類是線程安全的。 1. 概念 Spring的DAO異常體系建立在運行期異常的基礎上,封裝了源異常 JDBC數據訪問流程: 準備資源 啟動事務 在事務中執行具體數據...

    高璐 評論0 收藏0
  • 從動態代理到SpringAop以及AspectJ風格

    摘要:具體的動態代理運行原理這里暫不展開,網上有很多相關的內容,比如這篇翻譯過來就是面向方面切面編程。所以切面可以理解為和的集合。 1.靜態代理 在提及動態代理前先說明一下靜態代理模式,靜態代理模式是一種很常見的通用設計模式,實現也很簡單,uml類圖如下: showImg(https://segmentfault.com/img/bVba3gn?w=737&h=312); 如上圖所示,代理類...

    msup 評論0 收藏0
  • SpringBoot就是這么簡單

    摘要:熱加載代表的是我們不需要重啟服務器,就能夠類檢測得到,重新生成類的字節碼文件無論是熱部署或者是熱加載都是基于類加載器來完成的。驗證階段字節碼文件不會對造成危害準備階段是會賦初始值,并不是程序中的值。 一、SpringBoot入門 今天在慕課網中看見了Spring Boot這么一個教程,這個Spring Boot作為JavaWeb的學習者肯定至少會聽過,但我是不知道他是什么玩意。 只是大...

    whinc 評論0 收藏0
  • Spring AOP就是這么簡單啦

    摘要:是一種特殊的增強切面切面由切點和增強通知組成,它既包括了橫切邏輯的定義也包括了連接點的定義。實際上,一個的實現被拆分到多個類中在中聲明切面我們知道注解很方便,但是,要想使用注解的方式使用就必須要有源碼因為我們要 前言 只有光頭才能變強 上一篇已經講解了Spring IOC知識點一網打盡!,這篇主要是講解Spring的AOP模塊~ 之前我已經寫過一篇關于AOP的文章了,那篇把比較重要的知...

    Jacendfeng 評論0 收藏0
  • 慕課網_《Spring入門篇》學習總結

    摘要:入門篇學習總結時間年月日星期三說明本文部分內容均來自慕課網。主要的功能是日志記錄,性能統計,安全控制,事務處理,異常處理等等。 《Spring入門篇》學習總結 時間:2017年1月18日星期三說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:https://github.com/zccodere/s...個人學習源碼:https://git...

    Ververica 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<