AOP AspectJ註解

概念:html

切面(aspect):用來切插業務方法的類。
鏈接點(joinpoint):是切面類和業務類的鏈接點,其實就是封裝了業務方法的一些基本屬性,做爲通知的參數來解析。
通知(advice):在切面類中,聲明對業務方法作額外處理的方法。
切入點(pointcut):業務類中指定的方法,做爲切面切入的點。其實就是指定某個方法做爲切面切的地方。
目標對象(target object):被代理對象。
AOP代理(aop proxy):代理對象。java

AOP通知類型:
前置通知(before advice):在切入點以前執行。
後置通知(after returning advice):在切入點執行完成後,執行通知。
環繞通知(around advice):包圍切入點,調用方法先後完成自定義行爲。
異常通知(after throwing advice):在切入點拋出異常後,執行通知git

 

依賴包:spring

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.10</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.10</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/cglib/cglib -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.3.6.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>
View Code

Code:yii

package com.qhong;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Person person=(Person)context.getBean("babyPerson");
        person.eatBreakfast();
        System.out.println("===================================================");
        person.eatLunch();
        System.out.println("===================================================");
        person.eatSupper();
        System.out.println("===================================================");
        person.drink("可樂");
        System.out.println("===================================================");
   }
}

interface Person {
    public void eatBreakfast();
    public void eatLunch();
    public void eatSupper();
    public String drink(String name);
}

@Component
class BabyPerson implements Person{

    @Override
    public void eatBreakfast() {
        System.out.println("小Baby正在吃早餐");
    }

    @Override
    public void eatLunch() {
        System.out.println("小Baby正在吃午飯");
    }

    @Override
    public void eatSupper() {
        System.out.println("小Baby正在吃晚餐");
    }

    @Override
    public String drink(String name) {
        return "小Baby在喝:"+name;
    }
}

@Component
@Aspect
class AdivceMethod {

    @Before("execution(* com.qhong.BabyPerson.*(..))")
    // 匹配BabyPerson類全部的方法,注意*和com之間有個空格
    public void beforeEat() {
        System.out
                .println("-------------------這裏是前置加強,吃飯以前先洗小手!--------------------");
    }

    @After("execution(* eatLunch(..))")
    // 匹配該工程下全部的eatLunch方法
    public void afterEat() {
        System.out
                .println("-------------------這裏是後置加強,午餐吃完要睡午覺!--------------------");
    }

    @Around("execution(* com.qhong.BabyPerson.eatSupper())")
    // 匹配該工程下BabyPerson的eatLunch方法
    public Object aroundEat(ProceedingJoinPoint pjp) throws Throwable {
        System.out
                .println("-------------------這裏是環繞加強,吃晚飯前先玩一玩!-------------------");
        Object retVal = pjp.proceed();
        System.out
                .println("-------------------這裏是環繞加強,晚飯吃完後要得睡覺了!-------------------");
        return retVal;
    }
    @AfterReturning(returning="rvt",pointcut="execution(* com.qhong.BabyPerson.drink(..))")
    public void log(Object rvt) {
        System.out
                .println("-------------------這裏是AfterReturning加強-------------------");
        System.out.println("獲取小Baby正在喝的飲料"+rvt);
        System.out.println("記錄天天喝的飲料容量");

    }
}

beans.xmlide

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!-- 指定自動搜索bean組件、自動搜索切面類 -->
    <context:component-scan base-package="com.qhong"/>
    <!-- 啓動@AspectJ支持 -->
    <!-- proxy-target-class默認"false",更改成"ture"使用CGLib動態代理 -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
Result:
-------------------這裏是前置加強,吃飯以前先洗小手!--------------------
小Baby正在吃早餐
===================================================
-------------------這裏是前置加強,吃飯以前先洗小手!--------------------
小Baby正在吃午飯
-------------------這裏是後置加強,午餐吃完要睡午覺!--------------------
===================================================
-------------------這裏是環繞加強,吃晚飯前先玩一玩!-------------------
-------------------這裏是前置加強,吃飯以前先洗小手!--------------------
小Baby正在吃晚餐
-------------------這裏是環繞加強,晚飯吃完後要得睡覺了!-------------------
===================================================
-------------------這裏是前置加強,吃飯以前先洗小手!--------------------
-------------------這裏是AfterReturning加強-------------------
獲取小Baby正在喝的飲料小Baby在喝:可樂
記錄天天喝的飲料容量
===================================================


Spring + AspectJ(基於註解:經過 AspectJ execution 表達式攔截方法)
package com.qhong;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        com.qhong.Greeting greeting = (com.qhong.Greeting) context.getBean("greetingImpl");
        greeting.sayHello("Jack");
    }
}

interface Greeting {
    void sayHello(String name);
}

@Component
class GreetingImpl implements Greeting {
    @Override
    public void sayHello(String name) {
        System.out.println("Hello! " + name);
    }
}

@Aspect
@Component
class GreetingAspect {
    @Around("execution(* com.qhong.GreetingImpl.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        before();
        Object result = pjp.proceed();
        after();
        return result;
    }

    private void before() {
        System.out.println("Before");
    }

    private void after() {
        System.out.println("After");
    }
}

spring.xmlspa

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="com.qhong"/>

    <aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>

Result:.net

Before
Hello! Jack
After

 

遇到的bug代理

java.lang.NoClassDefFoundError: org/springframework/beans/factory/NoUniqueBeanDefinitionException

遇到這個問題應該是groupid是org.springframework的各個依賴之間版本相差太大形成的問題,全都改爲統一的就ok了。code

 

 

http://tonylit.me/2016/06/29/spring%20aop-AspectJ%E6%B3%A8%E8%A7%A3%E6%96%B9%E5%BC%8F/

http://www.yiibai.com/spring/spring-aop-aspectj-annotation-example.html

http://blog.csdn.net/xiaoxian8023/article/details/17285809

http://www.kancloud.cn/evankaka/springlearning/119670

http://git.oschina.net/lujianing/aop_demo

https://my.oschina.net/huangyong/blog/159788

https://my.oschina.net/huangyong/blog/161338

https://my.oschina.net/huangyong/blog/161402

https://my.oschina.net/huangyong/blog/160769

https://my.oschina.net/huangyong/blog/170494

相關文章
相關標籤/搜索