1. 程式人生 > >Spring-AOP切面+Aspectj框架的使用

Spring-AOP切面+Aspectj框架的使用

使用Aspectj框架進行AOP切面開發。

首先需要匯入兩個Jar包:
1. aspectjrt.jar
2. aspectjweaver-XXX.jar

Aspectj支援的五種註解:

  1. @Before: 前置通知, 在方法執行之前執行
  2. @After: 後置通知, 在方法執行之後執行
  3. @AfterReturning: 返回通知, 在方法返回結果之後執行
  4. @AfterThrowing: 異常通知, 在方法丟擲異常之後
  5. @Around: 環繞通知, 圍繞著方法執行

下面將使用兩種方式進行開發。

形式一 : 使用註解形式結合Spring,
切面:AudienceAdvice類

@Aspect
public class AudienceAdvice {
    /**
     *  1> execution() : 指明一個表示式
     *  2> * *..UserService.*(..): 表示式說明
     *      (1) * : 修飾符 --> 例如:public 或public void
     *      (2) *. : 任意包名或子包名 
     *      (3) .UserService : 該切面只對UserService介面生效
     *      (4) .* : 所有的方法
     *      (5) (..) :方法可以有任意引數
     * 
     * 作用:任意包下的UserServiceImpl的任意方法,觸發此AOP切面
     *  3> 表示式可以只寫一次,當其他註解繼續引用此表示式時,
     *     直接引用寫了表示式的方法名即可
     *     例如: init() 方法 和 after() 方法的註解形式
     * */
@Pointcut("execution(* *..UserService.*(..))") public void init(){}; /** * 之後 */ @After("init()") public void after(){ System.out.println("after"); } /** * 之前 */ @Before("init()") public void before(){ System.out.println("before"
); } /** * 環繞 */ @Around("init()") public void around(ProceedingJoinPoint jp){ System.out.println("before"); try { //執行方法 jp.proceed(); } catch (Throwable e) { e.printStackTrace(); } System.out.println("after"); } }

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:util="http://www.springframework.org/schema/util"
    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/util
        http://www.springframework.org/schema/util/spring-util-4.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

    <!-- service -->
    <bean id="userServiceImpl" 
            class="www.change.tm.springblank.service.impl.UserServiceImpl">
    </bean>

    <!-- 必須要注入此切面,即使下面引用了自動注入 -->
    <bean id="advice" 
        class="www.change.tm.springblank.aspectj.AudienceAdvice" />

    <!-- aop自動代理,此標籤必須引入 -->
    <aop:aspectj-autoproxy />
</beans>

UserServiceImpl類

public class UserServiceImpl implements UserService{
    @Override
    public void save() {

    }
}

Test部分

public class UserServiceTest {  
    @Test
    public void saveTest(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spr*.xml");
        UserService userDao = 
                applicationContext.getBean("userServiceImpl", UserService.class);
        userDao.save();
        applicationContext.close();
    }
}

形式二:使用XML配置Aspectj結合Spring
切面:AudienceAdvice

public class AudienceAdvice {

    public void init(){};

    /**
     * 之後
     */
    public void after(){
        System.out.println("after");
    }


    /**
     * 之前
     */
    public void before(){
        System.out.println("before");
    }

    /**
     * 環繞
     */
    public void around(ProceedingJoinPoint jp){
        System.out.println("before");
        try {
            jp.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("after");
    }

}

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:util="http://www.springframework.org/schema/util"
    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/util
        http://www.springframework.org/schema/util/spring-util-4.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.2.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">


    <bean id="userServiceImpl" class="www.change.tm.springblank.service.impl.UserServiceImpl">
    </bean>

    <!-- 注入切面 -->
    <bean id="advice" class="www.change.tm.springblank.aspectj.AudienceAdvice" />

    <!-- XML配置切面 -->
    <aop:config>
        <!-- 切面 -->
        <aop:aspect ref="advice">
            <!-- 切入點 -->
            <aop:pointcut expression="execution(* *..UserService.*(..))" id="mypoint"/>
            <!-- 
                method : 指定執行切面中(AudienceAdvice類)的哪個方法
                pointcut-ref : 指定切入點,什麼時候執行通知
            -->
            <!-- 前置通知 -->
            <!-- <aop:before method="before" pointcut-ref="mypoint"/> -->
            <!-- 環繞通知 -->
            <aop:around method="around" pointcut-ref="mypoint"/>
        </aop:aspect>
    </aop:config>

</beans>

UserServiceImpl服務層:

public class UserServiceImpl implements UserService{

    public UserServiceImpl() {
        System.out.println("初始化");
    }

    @Override
    public void save() {
        System.out.println("save");
    }

}

測試部分:

public class UserServiceTest {  
    @Test
    public void saveTest(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spr*.xml");
        UserService userDao = 
                applicationContext.getBean("userServiceImpl", UserService.class);
        userDao.save();
        applicationContext.close();
    }
}