1. 程式人生 > >使用Spring的註解方式實現AOP入門

使用Spring的註解方式實現AOP入門

單元測試 comment cast override src ioc ans 文件 返回

首先在Eclipse中新建一個普通的Java Project,名稱為springAOP。為了使用Spring的註解方式進行面向切面編程,需要在springAOP項目中加入與AOP相關的jar包,spring aop需要額外的jar包有:

  • com.springsource.org.aopalliance-1.0.0.jar
  • com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
  • spring-aop-4.2.5.RELEASE.jar
  • spring-aspects-4.2.5.RELEASE.jar

這樣,springAOP項目共須jar包如下:

技術分享
要進行AOP編程,我們接著要在Spring的配置文件——beans.xml中引入aop命名空間:

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

</beans>

Spring提供了兩種切面聲明方式,實際工作中我們可以選用其中一種:

  • 基於XML配置方式聲明切面。
  • 基於註解方式聲明切面。

本文選用第二種方式進行面向切面編程,即基於Spring註解的方式聲明切面。
接下來我們在src目錄下新建一個it.cast.service包,並在該包下創建PersonService接口,其代碼為:

public interface PersonService {
    public void save(String name);
    public void update(String name, Integer id);
    public String getPersonName(Integer id);
}
  • 1

緊接著在src目錄下新建一個it.cast.service.impl包,並在該包下創建PersonService接口的實現類——PersonServiceBean.java,其代碼為:

public class PersonServiceImpl implements PersonService {

    @Override
    public void save(String name) {
        System.out.println("我是save()方法");
    }

    @Override
    public void update(String name, Integer id) {
        System.out.println("我是update()方法");
    }

    @Override
    public String getPersonName(Integer id) {
        System.out.println("我是getPersonName()方法");
        return "xxx";
    }

}
  • 1
  • 2

然後,我們就要在cn.itcast.service包下創建一個切面類——MyInterceptor.java,下面我們來按照以下步驟將其寫出來。

  • [email protected]

    @Aspect
    public class MyInterceptor {
        ...
    }
  • [email protected]

    @Aspect
    public class MyInterceptor {
        @Pointcut("execution (* cn.itcast.service.impl.PersonServiceImpl.*(..))")
        private void anyMethod() {} // 聲明一個切入點,anyMethod為切入點名稱
        ...
    }

    我們可利用方法簽名來編寫切入點表達式。最典型的切入點表達式是根據方法的簽名來匹配各種方法:

    • execution (* cn.itcast.service.impl.PersonServiceImpl.*(..)):匹配PersonServiceImpl類中聲明的所有方法。第一個*代表任意修飾符及任意返回值類型,第二個*代表任意方法,..匹配任意數量任意類型的參數,若目標類與該切面在同一個包中,可以省略包名。
    • execution public * cn.itcast.service.impl.PersonServiceImpl.*(..):匹配PersonServiceImpl類中的所有公有方法。
    • execution public double cn.itcast.service.impl.PersonServiceImpl.*(..):匹配PersonServiceImpl類中返回值類型為double類型的所有公有方法。
    • execution public double cn.itcast.service.impl.PersonServiceImpl.*(double, ..):匹配PersonServiceImpl類中第一個參數為double類型,後面不管有無參數的所有公有方法,並且該方法的返回值類型為double類型。
    • execution public double cn.itcast.service.impl.PersonServiceImpl.*(double, double):匹配PersonServiceImpl類中參數類型為double,double類型的,並且返回值類型也為double類型的所有公有方法。
  • 然後聲明前置通知方法。
    前置通知方法在目標方法開始之前執行。

    @Aspect
    public class MyInterceptor {
        @Pointcut("execution (* cn.itcast.service.impl.PersonServiceImpl.*(..))")
        private void anyMethod() {} // 聲明一個切入點,anyMethod為切入點名稱
    
        // 聲明該方法是一個前置通知:在目標方法開始之前執行 
        @Before("anyMethod()")
        public void doAccessCheck() {
            System.out.println("前置通知");
        }
    }
    • 1

    註意:若是將一個類聲明為一個切面,那麽需要把該類放到IOC容器管理

接下來,我們理應要修改Spring的配置文件——beans.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: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-4.2.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

    <aop:aspectj-autoproxy />
    <bean id="myInterceptor" class="cn.itcast.service.MyInterceptor" />
    <bean id="personService" class=" cn.itcast.service.impl.PersonServiceImpl"></bean>
</beans>
  • 1

從上面可看出我們並沒有讓Spring自動掃描和管理Bean。
最後,在src目錄下新建一個junit.test包,並在該包中新建一個單元測試類——SpringAOPTest.java,其代碼為:

public class SpringAOPTest {

    @Test
    public void interceptorTest() {
        ApplicationContext cxt = new ClassPathXmlApplicationContext("beans.xml");
        PersonService personService = (PersonService) cxt.getBean("personService");
        personService.save("xxx");
    }

}
  • 1

測試interceptorTest()方法,會發現Eclipse控制臺打印:
技術分享
如要查看源碼,可點擊使用Spring的註解方式實現AOP入門進行下載。

使用Spring的註解方式實現AOP入門