您的位置:首页 > 编程语言 > Java开发

Spring中Aop的实现方式之一(基于动态代理)

2016-04-27 16:09 661 查看
Spring中重要的概念:基于AOP切面编程:(其实就是在方法的前后加入执行代码)

切面:Aspect:即由切入点(PointCut)和通知(Advice)

切入点:就是需要加入切面代码的地点(通常是某个方法名称,实际中用正则来匹配)。

通知:就是切入点发生后要做的事情,比如执行某段代码。

首先Spring支持5中通知:

(1)Before(前) org.apringframework.aop.MethodBeforeAdvice

(2)After-returning(返回后) org.springframework.aop.AfterReturningAdvice

(3)After-throwing(抛出后) org.springframework.aop.ThrowsAdvice

(4)Arround(周围) org.aopaliance.intercept.MethodInterceptor

(5)Introduction(引入) org.springframework.aop.IntroductionInterceptor

可以看出都是对某个方法进行通知(也证实了AOP的实际含义就是在某个方法前后加入代码段的概念)

先首先用代理模式怎么实现AOP

(1)创建通知:实现这几个接口,把其中的方法实现了

(2)创建切入点:一般通过正则匹配

(3)定义切面(把通知和切入点整合):常用的切面类有:

NameMatchMethodPointcutAdvisor,JdkRegexpMethodPointcut, DefaultPointcutAdvisor

(4)使用ProxyFactoryBean来生成代理,需指定要代理的接口和实现类,并把切面配置进去

具体:

1、先定义一个通知:用Arround

public class MethodAroundInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
System.out.println("Method around before " + arg0.getMethod().getName());
arg0.proceed(); //是否要调用切面代码
System.out.println("Method around after " + arg0.getMethod().getName());
return null;
}
配置通知:

<span style="white-space:pre">	</span><bean id="withAopAdvice" class="ray.interceptor.MethodAroundInterceptor"/>
2、定义一个切入点:

<bean id="withAopPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*withAop" />
</bean>


3、定义一个切面:(这里用DefaultPointcutAdvisor)

<bean id="withAopAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="withAopAdvice" />
<property name="pointcut" ref="withAopPointcut" />
</bean>


最后要在代理中配置

<bean id="aopServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" value="ray.aop.IAopService" />
<!-- 制定需要代理的对象(接口实现类) -->
<property name="target"> <ref bean="aopService" />
</property>
<!-- before - arround before - method - arround after - after -->
<property name="interceptorNames"><!-- 定义通知 -->
<list>
<value>withAopAdvisor</value>
</list>
</property>
</bean>


4、测试下:
private static void TestInterceptor() {
//通过代理类获得bean实例,其实是在代理类中方法执行前后加入代码
IAopService service = (IAopService)factory.getBean("aopServiceProxy");
//如果用构造函数或者工厂方法获得bean实例,不能实现AOP
//		IAopService service = (IAopService) factory.getBean("aopService");
service.withAop();
service.withOutAop();
}
看下输出:

Method around before withAop
run withAop method---------
Method around after withAop
run withOutAop method---------
另外:Spring给我们封装了几个常用的切面:

例如: NameMatchMethodPointcutAdvisor

上面的配置就可以这样配置了:

<!-- 要是拦截器在某个方法后执行,需要安装到NameMathched。。Advisor中 -->
<bean id="aopMethodThrowsExceptionInterceptor"
class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice">
<bean class="ray.interceptor.MethodThrowExceptionInterceptor"></bean>
</property>
<property name="mappedName" value=".*withAop"></property>
</bean>


只是把切入点的配置换成了mappedName而已,因为里面封装了mappedName为切入点:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: