的區別


原出處:https://blog.csdn.net/u011983531/article/details/70504281

轉自:https://www.jianshu.com/p/40f79da0cdef

在開發過程中,不少有Spring Aop的使用,在面向切面編程時,我們會使用< aop:aspect>;在進行事務管理時,我們會使用< aop:advisor>。那么,對於< aop:aspect>與< aop:advisor>的區別,具體是怎樣的呢?

至於兩者的區別,網上有很多資料,但是似乎都不能說清楚。
首先,我們需要明確兩者的概念。

  • < aop:aspect>:定義切面(切面包括通知和切點)
  • < aop:advisor>:定義通知器(通知器跟切面一樣,也包括通知和切點)

下面,我們列舉兩者的幾個區別。

1、實現方式不同

< aop:aspect>定義切面時,只需要定義一般的bean就行,而定義< aop:advisor>中引用的通知時,通知必須實現Advice接口。

下面我們舉例說明。 
首先,我們定義一個接口ISleepAdvisorable和這個接口的實現SleepImplAdvisor,代碼如下:

public interface ISleepAdvisorable
{
public void sleep(String name);
}


public class SleepImplAdvisor implements ISleepAdvisorable
{
private String name;

@Override
public String sleep(String name) {
System.out.println("I'm sleeping!");
return "sleep";
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

}

創建一個通知類,代碼如下:

public class AopAdvisorHelper implements MethodBeforeAdvice,AfterReturningAdvice
{
@Override
public void before(Method method, Object[] args, Object target) throws Throwable
{
System.out.println("類"+target+"執行了"+method.getName()+"方法。");
//數據庫做一個插入操作
}

/**
* returnValue 方法返回值
* method 執行的方法
* args 執行方法的參數
* target 執行的類
*/
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable
{
System.out.println("類"+target+"執行了"+method.getName()+"方法。");
}

}

創建spring-aop.xml文件,配置如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 開啟注解掃描 -->
<context:component-scan base-package="cn.ffcs.msa.springAop.four.aop.advisor"/>
<!-- aop配置 -->
<bean id="aopAdvisorHelper" class="cn.ffcs.msa.springAop.four.aop.advisor.AopAdvisorHelper"></bean>

<aop:config>
<aop:pointcut id="sleepPointcut" expression="execution(* cn.ffcs.msa.springAop.four.aop.advisor.*.*(..))"/>
<aop:advisor pointcut-ref="sleepPointcut" advice-ref="aopAdvisorHelper" />
</aop:config>
<bean id="human" class="cn.ffcs.msa.springAop.four.aop.advisor.SleepImplAdvisor"/>
<!-- <bean id="carable" class="cn.ffcs.msa.springAop.four.aop.advisor.CarableAdvisorImpl"/> -->
</beans>

測試類如下

public class App {

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

//aop-advisor實現aop攔截
private static void method1()
{
ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");
ISleepAdvisorable sleeper = (ISleepAdvisorable) context.getBean("human");
sleeper.sleep("human");
System.out.println("=======================================");
ICarAdvisorable car = (ICarAdvisorable) context.getBean("carableAdvisorImpl");
car.byCar();
}
}

==================================================================================

下面是< aop:aspect>的實現方式:

首先,我們定義一個接口ISleepAdvisorable和這個接口的實現SleepImplAdvisor,代碼如下:

public interface ISleepAspectable
{
String sleep(String name);
}

public class HumanAspect implements ISleepAspectable
{
private String name;

@Override
public String sleep(String name) {
System.out.println("I'm sleeping!");
return "sleep";
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

創建通知類,代碼如下:

public class AopAspectHelper
{
public void aopBefore(JoinPoint joinPoint)
{
System.out.println(joinPoint.getSignature().getName());
System.out.println(joinPoint.getTarget());
System.out.println(Arrays.toString(joinPoint.getArgs()));
System.out.println("read to sleep !");
//數據庫做一個插入操作
}

/**
* returnValue 方法返回值
* method 執行的方法
* args 執行方法的參數
* target 執行的類
*/
public void aopAfter(JoinPoint joinPoint)
{
System.out.println("I'm awake.");
}

}

創建spirng-aop2配置文件,配置如下:

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

<bean id="human" class="cn.ffcs.msa.springAop.four.aop.aspect.HumanAspect"/>
<bean id="carable" class="cn.ffcs.msa.springAop.four.aop.aspect.CarableAspectImpl"/>
<bean id="aopAspectHelper" class="cn.ffcs.msa.springAop.four.aop.aspect.AopAspectHelper"/>

<aop:config>
<aop:pointcut id="aopPointcut" expression="execution(* cn.ffcs.msa.springAop.four.aop..*.*(..))"/>
<aop:aspect ref="aopAspectHelper">
<!--前置通知-->
<aop:before method="aopBefore" pointcut-ref="aopPointcut"/>
<!--后置通知-->
<aop:after method="aopAfter" pointcut-ref="aopPointcut" />
</aop:aspect>
</aop:config>
</beans>

項目用到的maven的jar包管理如下:

 

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>

2、使用場景不同
< aop:advisor>大多用於事務管理。
例如:

其實,不管是< aop:advisor>還是< aop:aspect>最終的實現邏輯是一樣的。

小結:
可以看出,< aop:advisor>和< aop:aspect>其實都是將通知和切面進行了封裝,原理基本上是一樣的,只是使用的方式不同而已。


免責聲明!

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



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