AOP的實現

  1. spring對AOP的實現(只有配置式)
    前置通知(MethodBeforeAdvice)
    後置通知(AfterReturingAdvice)
    環繞通知(MethodInteceptor)
    異常通知(ThrowsAdvice)
    首先要導入支持AOP的兩個jar包
    在這裏插入圖片描述
    定義目標類
public class SomeServiceImpl implements IsomeService {
    @Override
    public void doSome() {
        System.out.println("-----doSome方法執行!------"+1/0);
    }

    @Override
    public String doOther() {
        System.out.println("-----doOther方法執行!------");
        return "xioabai";
    }
}

主業務接口

public interface IsomeService {
    //目標方法
    public void doSome();
    public String doOther();
}

定義切面類(通知類,這裏以後置通知爲例)

public class MyAfterReturingAdvice implements AfterReturningAdvice {
    @Override
    public void **afterReturning**(Object **returnValue**, Method method, Object[] args, Object target) throws Throwable {
        if(returnValue!=null){
            returnValue=returnValue.toString().toUpperCase();
        }
        System.out.println("-----後置通知-------"+returnValue);
    }
}

在配置文件中註冊目標類

 <!--註冊目標類 -->
    <bean id="someServiceImpl" class="com.hxh.service.impl.SomeServiceImpl"></bean>

註冊切面:後置通知

 <bean id="myMethodBeforeAdvice" class="com.hxh.aspect.MyMethodBeforeAdvice"></bean>
    <!--後置通知-->
    <bean id="myAfterReturingAdvice" class="com.hxh.aspect.MyAfterReturingAdvice"></bean>

註冊動態代理工廠ProxyFactoryBean(建立目標類和切面類的聯繫)

 <bean id="proxyFactoryBean" class="**org.springframework.aop.framework.ProxyFactoryBean**">
        <property name="**target**" ref="someServiceImpl"></property>
        <property name="**interfaces**" value="com.hxh.service.IsomeService"></property>//可以不寫
        <property name="**interceptorNames**" value="myThrowsAdvice"></property>
    </bean>

客戶端訪問動態代理對象

public class TestStar {
    @Test
    public void testSpring(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
        IsomeService proxy = ac.getBean("**proxyFactoryBean**", IsomeService.class);
        proxy.doSome();
        String s=proxy.doOther();
        System.out.println(s);
    }
}
  1. AspectJ對AOP的實現(既支持配置式開發也支持註解式開發,可以指定時間點、切入點)
    前置通知
    後置通知
    環繞通知
    異常通知
    最終通知(無論程序是否執行該通知都會執行,同try-catch-finally中finally的功能,常用於關閉資源)
    在實現的過程中用到切入點表達式在此簡單介紹:
    exection([modifiers-pattern]訪問權限
    ret-type-pattern 返回值類型
    [declaring-type-pattern] 全限定性類名
    name-pattern(param-pattern)
    [throws-pattern] 拋出異常類型)
    切入點表達式要匹配的對象就是目標方法的方法名。所以,execution表達式中明顯就是方法的簽名。注意,表達式中加[ ]的部分表示可省略部分,各部分間用空格分開。在其中可以使用以下符號:
    :0至多個任意字符
    …:用在方法參數中,表示任意多個參數;用在包名後,表示當前包及其子包路徑
    +:用在類名後,表示當前類及其子類;用在接口後,表示當前接口及其實現類
    舉例:
    execution(public * (…))
    指定切入點爲:任意公共方法。
    execution(
    set (…))
    指定切入點爲:任何一個以"set"開始的方法。
    execution(
    com.xyz.service.
    .(…))
    指定切入點爲:定義在service包裏的任意類的任意方法。
    execution(
    com.xyz.service….(…))
    指定切入點爲:定義在service包或者子包裏的任意類的任意方法。"…“出現在類名中時, 後面必須跟”",表示包、子包下的所有類。
    execution(
    .service..(…))
    指定只有一級包下的serivce子包下所有類(接口)中的所有方法爲切入點
    execution(
    …service..*(…))
    指定所有包下的serivce子包下所有類(接口)中的所有方法爲切入點
    註解式
    1.導入相應的jar包,引入AOP約束
    在這裏插入圖片描述
    2.編寫切面類MyAspect(用到@Aspect–類體上表明當前類是一個切面)
		***@Aspect***
		public class MyAspect {
		    //前置通知
		    ***@Before("execution(* *..service.*.doSome(..))")***
		    public void before(){
		        System.out.println("-----前置通知-------");
		    }
		    //後置通知
		    **@AfterReturning(value="execution(* *..service.*.doOther(..))",*returning = "result"*)**
		    public void afterReturing(Object result){
		        if(result!=null){
		            result=result.toString().toUpperCase();
		        }
		        System.out.println("-----後置通知----"+result);
		    }
		    //環繞通知
		    ***@Around("execution(* *..service.*.doOther(..))")***
		    public void aroud(ProceedingJoinPoint pjp){
		        try {
		            System.out.println("-----環繞通知--目標方法執行前---");
		            Object result = pjp.proceed();
		            System.out.println("-----環繞通知--目標方法執行後---"+result);
		        } catch (Throwable throwable) {
		            throwable.printStackTrace();
		        }
		    }
		    //異常通知
		    **@AfterThrowing(value="execution(* *..service.*.doSome(..))",throwing ="ex")**
		    public void throwing(Exception ex){
		        System.out.println("----異常通知-------"+ex);
		    }
		    //最終通知
		    ***@After("execution(* *..service.*.doSome(..))")***
		    public void after(){
		        System.out.println("-----最終通知------");
		    }
		}```
     3.配置文件中註冊切面
<bean id="myAspect" class="com.hxh.aspect.MyAspect"></bean>
   4.註冊AOP自動代理
	```
	<aop:aspectj-autoproxy/>
	```
  5.測試類測試

public class TestStar {
@Test
public void testSpring(){
ApplicationContext ac = new ClassPathXmlApplicationContext(“spring.xml”);
IsomeService proxy = ac.getBean(“someServiceImpl”, IsomeService.class);
proxy.doSome();
String s=proxy.doOther();
System.out.println(s);
}
}

**配置式**
 1.在配置文件中進行AOP配置
 <aop:config>
 	<aop:aspect ref="切面類">
 前置通知
 		<aop:before  method="方法名" pointcut-ref=id>
 		<aop:pointcut id="唯一" expression="切入點表達式"
 		帶返回值的加一個
 		returning="方法中的參數">
<bean id="someServiceImpl" class="com.hxh.service.impl.SomeServiceImpl"></bean>
<bean id="myAspect" class="com.hxh.aspect.MyAspect"></bean>
<!--註冊AOP配置-->
<aop:config>
    <aop:pointcut id="doSomePc" expression="execution(* *..service.*.doSome(..))"></aop:pointcut>
    <aop:pointcut id="doOtherPc" expression="execution(* *..service.*.doOther(..))"></aop:pointcut>
    <aop:aspect ref="myAspect">
        <!--前置通知-->
        <aop:before method="before" pointcut-ref="doSomePc"></aop:before>
        <!--後置通知-->
        <aop:after-returning method="afterReturing" pointcut-ref="doOtherPc" returning="result"></aop:after-returning>
        <!--環繞通知-->
        <aop:around method="around" pointcut-ref="doOtherPc"></aop:around>
        <!--異常通知-->
        <aop:after-throwing method="throwing" pointcut-ref="doSomePc" throwing="ex"></aop:after-throwing>
        <!--最終通知-->
        <aop:before method="after" pointcut-ref="doSomePc"></aop:before>
    </aop:aspect>
</aop:config>
Spring、AspectJ和AOP的關係:
		對於AOP這種編程思想,很多框架都進行了實現,Spring就是其中之一,可以完成面向切面編程。然而,AspectJ也實現了AOP的功能,且實現方式更爲便捷,使用更爲方便,而且還支持註解式開發。所以,spring又將AspectJ對於AOP的實現也引入到自己的框架中。
		在Spring中使用AOP開發時,一般使用AspectJ的實現方式。
發佈了45 篇原創文章 · 獲贊 9 · 訪問量 2464
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章