Spring中實現AOP的兩種方式

來源:互聯網
上載者:User

這裡示範的是Spring中使用AspectJ註解和XML配置兩種方式實現AOP

下面是使用AspectJ註解實現AOP的Java Project

首先是位於classpath下的applicationContext.xml檔案

<?xml version="1.0" encoding="UTF-8"?><br /><beans xmlns="http://www.springframework.org/schema/beans"<br />xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />xmlns:aop="http://www.springframework.org/schema/aop"<br />xmlns:tx="http://www.springframework.org/schema/tx"<br />xsi:schemaLocation="<br />http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd<br />http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd<br />http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"></p><p><!-- 啟用AspectJ對Annotation的支援 --><br /><aop:aspectj-autoproxy/></p><p><bean id="userManager" class="com.jadyer.annotation.UserManagerImpl"/></p><p><bean id="securityHandler" class="com.jadyer.annotation.SecurityHandler"/><br /></beans>

然後是服務層介面以及實作類別

package com.jadyer.annotation;<br />public interface UserManager {<br />public void addUser(String username, String password);<br />public void delUser(int userId);<br />public String findUserById(int userId);<br />public void modifyUser(int userId, String username, String password);<br />}</p><p>/**<br /> * 上面的UserManager是服務層的介面<br /> * 下面的UserManagerImpl是服務層介面的實作類別<br /> */</p><p>package com.jadyer.annotation;</p><p>public class UserManagerImpl implements UserManager {<br />public void addUser(String username, String password) {<br />System.out.println("------UserManagerImpl.addUser() is invoked------");<br />}</p><p>public void delUser(int userId) {<br />System.out.println("------UserManagerImpl.delUser() is invoked------");<br />}</p><p>public String findUserById(int userId) {<br />System.out.println("------UserManagerImpl.findUserById() is invoked------");<br />return "鐵面生";<br />}</p><p>public void modifyUser(int userId, String username, String password) {<br />System.out.println("------UserManagerImpl.modifyUser() is invoked------");<br />}<br />}

接下來是使用AspectJ註解標註的切入類

package com.jadyer.annotation;</p><p>import org.aspectj.lang.annotation.After;<br />import org.aspectj.lang.annotation.Aspect;<br />import org.aspectj.lang.annotation.Pointcut;</p><p>@Aspect<br />public class SecurityHandler {<br />/**<br /> * 定義Pointcut<br /> * @see Pointcut的名稱為addAddMethod(),此方法沒有傳回值和參數<br /> * @see 該方法就是一個標識,不進行調用<br /> */<br />@Pointcut("execution(* add*(..))") //匹配所有以add開頭的方法<br />private void addAddMethod(){};</p><p>/**<br /> * 定義Advice<br /> * @see 表示我們的Advice應用到哪些Pointcut訂閱的Joinpoint上<br /> */<br />//@Before("addAddMethod()")<br />@After("addAddMethod()")<br />private void checkSecurity() {<br />System.out.println("------【checkSecurity is invoked】------");<br />}<br />}

最後是用戶端測試類別

package com.jadyer.annotation;</p><p>import org.springframework.context.ApplicationContext;<br />import org.springframework.context.support.ClassPathXmlApplicationContext;</p><p>/**<br /> * Spring對AOP的支援:採用Annotation方式<br /> * @see -------------------------------------------------------------------------------------<br /> * @see Spring提供的AOP功能還是很強大的,支援可配置,它的預設實現使用的就是JDK動態代理<br /> * @see 使用Spring的AOP不需要繼承相關的東西,也不需要實現介面<br /> * @see 但有個前提條件:由於是JDK動態代理,所以若想組建代理程式,該類就必須得實現一個介面才行<br /> * @see 如果該類沒有implements介面的話,仍去使用Spring的預設AOP實現時,那麼就會出錯<br /> * @see 通常需要組建代理程式的類都是服務層的類,所以通常都會抽一個介面出來。即養成面向介面編程的習慣<br /> * @see -------------------------------------------------------------------------------------<br /> * @see 採用Annotation方式完成AOP樣本的基本步驟,如下<br /> * @see 1、Spring2.0的依賴包配置。新增Annotation支援<br /> * @see * SPRING_HOME//dist//spring.jar<br /> * @see * SPRING_HOME//lib//log4j//log4j-1.2.14.jar<br /> * @see * SPRING_HOME//lib//jakarta-commons//commons-logging.jar<br /> * @see * SPRING_HOME//lib//aspectj//*.jar<br /> * @see 2、將橫切性關注點模組化,建立SecurityHandler.java<br /> * @see 3、採用註解指定SecurityHandler為Aspect<br /> * @see 4、採用註解定義Advice和Pointcut<br /> * @see 5、啟用AspectJ對Annotation的支援,並且將目標類和Aspect類配置到IoC容器中<br /> * @see 6、開發用戶端<br /> * @see -------------------------------------------------------------------------------------<br /> */<br />public class Client {<br />public static void main(String[] args) {<br />ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml");<br />UserManager userManager = (UserManager)factory.getBean("userManager");<br />userManager.addUser("張起靈", "02200059");<br />}<br />}

下面是使用XML設定檔實現AOP的Java Project

首先是位於src根目錄中的applicationContext-cglib.xml檔案

<?xml version="1.0" encoding="UTF-8"?><br /><beans xmlns="http://www.springframework.org/schema/beans"<br />xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />xmlns:aop="http://www.springframework.org/schema/aop"<br />xmlns:tx="http://www.springframework.org/schema/tx"<br />xsi:schemaLocation="<br />http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd<br />http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd<br />http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"></p><p><!-- 強制使用CGLIB代理 --><br /><!-- <aop:aspectj-autoproxy proxy-target-class="true"/> --></p><p><bean id="userManager" class="com.jadyer.cglib.UserManagerImpl"/></p><p><bean id="securityHandler" class="com.jadyer.cglib.SecurityHandler"/></p><p><aop:config><br /><aop:aspect id="securityAspect" ref="securityHandler"><br /><aop:pointcut id="addAddMethod" expression="execution(* add*(..))"/><br /><aop:before method="checkSecurity" pointcut-ref="addAddMethod"/><br /></aop:aspect><br /></aop:config><br /></beans></p><p><!--<br />匹配add開頭的所有的方法<br />execution(* add*(..))</p><p>匹配com.jadyer.servcices.impl包下的所有的類的所有的方法<br />execution(* com.jadyer.servcices.impl.*.*(..))</p><p>匹配com.jadyer.servcices.impl包下的add或者del開頭的所有的方法<br />execution(* com.jadyer.servcices.impl.*.add*(..)) || execution(* com.jadyer.servcices.impl.*.del*(..))<br /> -->

然後是服務層介面以及實作類別

package com.jadyer.cglib;<br />public interface UserManager {<br />public void addUser(String username, String password);<br />public void delUser(int userId);<br />public String findUserById(int userId);<br />public void modifyUser(int userId, String username, String password);<br />}</p><p>/**<br /> * 上面的UserManager是服務層介面<br /> * 下面的UserManagerImpl是服務層介面的實作類別<br /> */</p><p>package com.jadyer.cglib;</p><p>public class UserManagerImpl {<br />//implements UserManager {<br />public void addUser(String username, String password) {<br />System.out.println("------UserManagerImpl.addUser() is invoked------");<br />}</p><p>public void delUser(int userId) {<br />System.out.println("------UserManagerImpl.delUser() is invoked------");<br />}</p><p>public String findUserById(int userId) {<br />System.out.println("------UserManagerImpl.findUserById() is invoked------");<br />return "張三";<br />}</p><p>public void modifyUser(int userId, String username, String password) {<br />System.out.println("------UserManagerImpl.modifyUser() is invoked------");<br />}<br />}

接著是在applicationContext-cglib.xml中所指定的切入類

package com.jadyer.cglib;</p><p>import org.aspectj.lang.JoinPoint;</p><p>/**<br /> * 將客戶調用資訊傳遞到該Advice中<br /> * @see 可以在Advice中添加一個JoinPoint參數,取得用戶端調用的方法名稱及參數值<br /> * @see 以後純粹使用AOP去寫類似這樣東西的情況比較少,我們主要使用Spring提供的事務<br /> * @see 關於這個,知道即可。下面是範例程式碼<br /> */<br />public class SecurityHandler {<br />private void checkSecurity(JoinPoint joinPoint) {<br />for (int i=0; i<joinPoint.getArgs().length; i++) {<br />System.out.println(joinPoint.getArgs()[i]); //擷取用戶端調用的方法的參數值<br />}<br />System.out.println(joinPoint.getSignature().getName()); //擷取用戶端調用的方法名稱<br />System.out.println("------【checkSecurity is invoked】------");<br />}<br />}

最後是用戶端測試類別

package com.jadyer.cglib;</p><p>import org.springframework.context.ApplicationContext;<br />import org.springframework.context.support.ClassPathXmlApplicationContext;</p><p>/**<br /> * @see --------------------------------------------------------------------------------------------------<br /> * @see JDK動態代理和CGLIB代理的差別<br /> * @see 1..JDK動態代理對實現了介面的類進行代理<br /> * @see 2..CGLIB代理可以對類代理,主要對指定的類產生一個子類。由於是繼承,所以目標類最好不要使用final聲明<br /> * @see --------------------------------------------------------------------------------------------------<br /> * @see 代理方式的選擇<br /> * @see 1..如果目標對象實現了介面,預設情況下會採用JDK動態代理實現AOP,亦可強制使用CGLIB組建代理程式實現AOP<br /> * @see 2..如果目標對象未實現介面,那麼必須引入CGLIB,這時Spring會在JDK動態代理和CGLIB代理之間自動切換<br /> * @see 3..比較鼓勵業務對象是針對介面編程的,所以鼓勵使用JDK動態代理。因為我們所代理的目標,一般都是業務對象<br /> * @see --------------------------------------------------------------------------------------------------<br /> * @see 使用CGLIG代理的步驟<br /> * @see 1..新增CGLIB庫:SPRING_HOME//lib//cglib//*.jar<br /> * @see 2..新增配置標籤,強制使用CGLIB代理<aop:aspectj-autoproxy proxy-target-class="true"/><br /> * @see --------------------------------------------------------------------------------------------------<br /> */<br />public class Client {<br />public static void main(String[] args) {<br />ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext-cglib.xml");</p><p>//當UserManagerImpl實現了UserManager介面的情況下,這時Spring會自動使用JDK動態代理<br />//如果項目已經引入cglib庫,並在設定檔中強制使用CGLIB代理,此時Spring才會使用CGLIB代理<br />//UserManager userManager = (UserManager)factory.getBean("userManager");</p><p>//由於此時的UserManagerImpl並沒有實現UserManager介面,所以接收類型就不能再使用UserManager介面<br />//並且項目中已經引入了cglib庫,儘管設定檔中沒有強制使用CGLIB代理,但Spring會自動使用CGLIB代理<br />UserManagerImpl userManager = (UserManagerImpl)factory.getBean("userManager");</p><p>userManager.addUser("吳三省", "02200059");<br />}<br />}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.