写点什么

Spring 之 AOP 适配器模式

  • 2021 年 11 月 11 日
  • 本文字数:1941 字

    阅读完需:约 6 分钟


Spring 中适配器模式


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


一、AOP 案例




Spring 中的 AOP 的实现方式有多种,而且每种实现方式中的通知类型也比较多,本文以 Spring 自带的 Schema-base 方式中的前置通知来说明。详细介绍移步 Spring之AOP详解

1.相关依赖

<dependency>


<groupId>org.springframework</groupId>


<artifactId>spring-context</artifactId>


<version>4.3.21.RELEASE</version>


</dependency>


<dependency>


<groupId>junit</groupId>


<artifactId>junit</artifactId>


<version>4.12</version>


</dependency>


<dependency>


<groupId>aopalliance</groupId>


<artifactId>aopalliance</artifactId>


<version>1.0</version>


</dependency>

2.创建目标对象

/**


  • 目标对象 接口

  • @author 波波烤鸭

  • @email dengpbs@163.com


*/


public interface SomeService {


public void doSome();


}


/**


  • 目标对象

  • @author 波波烤鸭

  • @email dengpbs@163.com


*/


public class SomeServiceImpl implements SomeService {


@Override


public void doSome() {


System.out.println("目标对象....方法执行了");


}


}

3.创建通知

/**


  • 前置通知

  • @author 波波烤鸭

  • @email dengpbs@163.com


*/


public class MyMethodBeforeAdvice implements MethodBeforeAdvice {


/**


  • method 目标方法

  • args 目标方法参数列表

  • target 目标对象


*/


@Override


public void before(Method method, Object[] args, Object target) throws Throwable {


System.out.println("前置通知执行了....");


}


}

4.配置文件

<beans xmlns="http://www.springframework.org/schema/beans"


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"


xmlns:context="http://www.springframework.org/schema/context"


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.3.xsd">


<bean id="someServiceImpl" class="com.dpb.service.SomeServiceImpl" ></bean>


<bean class="com.dpb.schema.MyMethodBeforeAdvice" id="myMethodBeforeAdvice"></bean>


<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">


<property name="target" ref="someServiceImpl"/>


<property name="interfaces" value="com.dpb.service.SomeService"/>


<property name="interceptorNames" >


<list>


<value>myMethodBeforeAdvice</value>


</list>


</property>


</bean>


</beans>

5.测试

@Test


public void test1() {


ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");


// 注意通过 getBean 获取增强的代理类!!!


SomeService some = ac.getBean("proxyFactoryBean",SomeService.class);


some.doSome();


}


输出:



说明我们配置的前置通知生效了,在目标方法执行之前执行了。


二、适配器应用解析



1.Advice 体系结构


说明:


  1. advice 的类型有:BeforeAdvice,AfterReturningAdvice,ThrowsAdvice 等

  2. 每个类型的通知都有对应的拦截器


| advice | 拦截器 |


| --- | :-- |


| BeforeAdvice | MethodBeforeAdviceInterceptor |


| AfterAdvice | AfterReturningAdviceInterceptor |


| AfterAdvice | ThrowsAdviceInterceptor |


  1. Spring 容器需要将每个具体的 advice 封装成对应的拦截器,返回给容器,这里对 advice 转换就需要用到适配器模式。

2.适配器的实现

以前置通知为例

2.1Adaptee

MethodBeforeAdvice


public interface MethodBeforeAdvice extends BeforeAdvice {


void before(Method method, Object[] args, Object target) throws Throwable;


}

2.2target

Adapter 的接口 AdvisorAdapter


public interface AdvisorAdapter {


// 判断通知类型是否匹配


boolean supportsAdvice(Advice advice);


// 获取对应的拦截器


MethodInterceptor getInterceptor(Advisor advisor);


}

2.3Adapter

MethodBeforeAdviceAdapter


class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {


@Override


public boolean supportsAdvice(Advice advice) {


return (advice instanceof MethodBeforeAdvice);


}


@Override


public MethodInterceptor getInterceptor(Advisor advisor) {


MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();


// 通知类型匹配对应的拦截器


return new MethodBeforeAdviceInterceptor(advice);


}


}

2.4Client

代理类通过 DefaultAdvisorAdapterRegistry 类来注册相应的适配器。





public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {

评论

发布
暂无评论
Spring之AOP适配器模式