spring框架應用系列三:切面編程(帶參數)


                                      切面編程(帶參數)                                                   

                                                              本文系作者原創,轉載請注明出處:http://www.cnblogs.com/further-further-further/p/7786715.html

解決問題

1、分離業務監控與業務處理。簡單點說,讓開發人員更專注業務邏輯開發,類似於打印日志、統計時間、監控等等獨立成一個單獨的類,在需要的時候,動態的將代碼切入到類的指定方法上,使方法擁有更強大的功能;

2、解決代碼重復性,降低代碼復雜程度;

內容說明

1、通過@Component注解,掃描(Magician)bean並注冊到spring容器中時,需在XML配置文件中引入 <context:component-scan base-package="com.spring.example.aspectArgs"/>;

2、明確切面、切點、通知概念,這里切面是Magician,切點是Volunteer的thinkOfSomething方法,通知是Magician中所包含方法,由xml或注解配置,下面會分別給出示例;

3、通過執行Volunteer的thinkOfSomething方法,從而執行Magician中相應的方法,達到通知的效果;


應用實例:截聽志願者內心真實想法

先列出相關接口以及類代碼

切面實現接口MindReader(讀心者)

package com.spring.example.aspectAspectJArgs;

//讀心者
public interface MindReader {
    void interceptThoughts(String thoughts);
    void getConclusion(String thoughts);
}

切點類志願者實現接口Thinker

package com.spring.example.aspectAspectJArgs;

/**
 * 讀心者賦予一個他需要截聽內心感應的志願者
 */
public interface Thinker {
    void thinkOfSomething(String thoughts);
}

志願者實體類Volunteer

package com.spring.example.aspectAspectJArgs;

import org.springframework.stereotype.Component;

/**
 * Created by weixw on 2017/10/24.
 */
@Component
public class Volunteer implements Thinker {

    private String thoughts;
    @Override
    public void thinkOfSomething(String thoughts) {
        this.thoughts = thoughts;

    }

}

以下有兩種方式實現此實例的切面編程:一、通過XML配置文件,二、AspectJ注解方式

其他代碼都相同,不同處在spring 的xml配置文件以及切面類文件

一、通過XML配置文件:

切面(讀心者)實體類

package com.spring.example.aspectArgs;

/**
 * Created by weixw on 2017/10/24.
 */

import org.springframework.stereotype.Component;

/**
 * 截聽志願者的內心感應和顯示他們在想什么
 */
@Component
public class Magician implements MindReader {

    @Override
    public void interceptThoughts(String thoughts) {
        System.out.println("Intercepting volunteer's thoughts :" +thoughts);
    }

    @Override
    public void getConclusion(String thoughts) {
        System.out.println("For your thoughts :" +thoughts);
        System.out.println("I think you are right.");
    }

}


spring 配置文件 aspect-args.xml

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd  http://www.springframework.org/schema/aop 

http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context 

http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.spring.example.aspectArgs"/>

    <aop:config>
           <!--通過component-scan自動掃描,@Component注解將Magician注冊到spring容器-->
            <aop:aspect ref="magician">
                <aop:pointcut id="thinking" expression="execution(* 

com.spring.example.aspectArgs.Thinker.thinkOfSomething(String))
                             and args(thoughts)"/>
                <aop:before pointcut-ref="thinking" method="interceptThoughts" arg-names="thoughts"/>
                <aop:after pointcut-ref="thinking" method="getConclusion" arg-names="thoughts"/>
            </aop:aspect>
    </aop:config>
</beans>
View Code

二 、AspectJ注解方式

切面(讀心者)實體類

package com.spring.example.aspectAspectJArgs;

/**
 * Created by weixw on 2017/10/24.
 */

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 截聽志願者的內心感應和顯示他們在想什么
 */
@Component
@Aspect
public class Magician implements MindReader {

    @Pointcut("execution(* com.spring.example.aspectAspectJArgs.Thinker.thinkOfSomething(String)) " +
            "&& args(thoughts)") //定義切點
    public void thinkOfSomething(String thoughts){}
    @Before("thinkOfSomething(thoughts)")
    @Override
    public void interceptThoughts(String thoughts) {
        System.out.println("Intercepting volunteer's thoughts :" +thoughts);
    }
    @AfterReturning("thinkOfSomething(thoughts)")
    @Override
    public void getConclusion(String thoughts) {
        System.out.println("For your thoughts :" +thoughts);
        System.out.println("I think you are right.");
    }

}


spring 配置文件 aspect-aspectJArgs.xml

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd  http://www.springframework.org/schema/aop 

http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context 

http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.spring.example.aspectAspectJArgs"/>
    <aop:aspectj-autoproxy/>
   
</beans>

測試代碼

注解測試代碼如下,配置文件測試代碼只需將配置文件名稱改成spring/aspect-args.xml即可

package com.spring.example.aspectAspectJArgs;/**
 * Created by weixw on 2017/10/19.
 */

import javafx.application.Application;
import javafx.stage.Stage;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Driver extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        try {

            ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/aspect-aspectJArgs.xml");
            Thinker thinker = (Thinker) ctx.getBean("volunteer");
            thinker.thinkOfSomething("I'm stupid.");

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
View Code

運行結果

 

 

總結

  上述列出配置文件和注解兩種方式都能實現切面編程。但對於自身業務開發,個人覺得注解方式較好,因為在修改某一切面類時不需要多處修改;

 

本文描述可能有不對或不全之處,歡迎大家吐槽!

 

不要讓懶惰占據你的大腦,不要讓妥協拖垮你的人生。青春就是一張票,能不能趕上時代的快車,你的步伐掌握在你的腳下。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM