科帮网

登录/注册
您现在的位置:论坛 盖世程序员(我猜到了开头 却没有猜到结局) 盖世程序员 > AOP及其在Spring中的应用
总共48087条微博

动态微博

查看: 1311|回复: 0

AOP及其在Spring中的应用

[复制链接]

57

主题

5

听众

129

金钱

三袋弟子

该用户从未签到

跳转到指定楼层
楼主
发表于 2015-02-08 12:19:17 |只看该作者 |倒序浏览
spring中AOP的实现就是通过动态代理来实现的。动态代理的实现在上篇blog中已经涉及。Spring中目前最为实用的AOP应用,非用其实现的事务管理机制莫属。也正是这一点,使得Spring AOP大方异彩。
$ E1 n. k7 Q0 V# U+ ]! c; A- d2 j那么我们继续围绕上节的例子来探讨一下Spring中AOP机制的应用与开发。

  首先,看看AOP中几个基本的概念对应在AOP中的实现: 6 J" A2 m& Q& B3 E& p
? 切点(PointCut) , b! |: X2 L8 z: D; X
  一系列连接点的集合,它指明处理方式(Advice)将在何时被触发。
9 |8 T1 d6 Y1 y' p  对于我们开发而言,“何时触发”的条件大多是面向Bean的方法进行制定。像Spring的配置化事务管理时针对方法名称可进行PointCut设置,从而指定对所有以声明字符开头的方法进行基于AOP的事务管理。那么同样,对于我们自己实现的AOP组件而言,我们也可以以方法名作为触发判定条件。8 b  K4 t  d0 b/ y. Z, s
我们可以通过在XML配置文件中配置以下节点,为我们的组件设定触发条件。
+ {) Q; c9 q' B1 {<bean id="myPointcutAdvisor" % P& {3 b. v  `9 j
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
$ o: q& p* J2 K: a<property name="advice"> 9 }4 ?+ G5 P. k  {
<ref local="MyInterceptor" />
0 z5 K" X, X+ `+ l0 j</property>
4 g1 P; j" y2 _3 a2 w<property name="patterns"> 5 ~* h3 M. A! T5 [3 n; r2 U
<list> $ T9 ^7 O. o6 I% H
<value>.*save.*</value>
. I6 G* T$ ~) r5 A) i' e! l: Q<value>.*do.*</value>
6 @: b- C* h* x% _1 t; Y" C</list> 5 O5 ~0 E9 I1 |# M8 x# w3 S4 `
</property> 6 F* Y$ l- N( H1 z
</bean>

  上面我们针对MyInterceptor设定了一个基于方法名的触发条件,也就是说,当目标类的指定方法运行时,MyInterceptor即被触发。 + C# ?; V  E% b3 [0 p5 H0 ^
  ? 处理方式(Advice) ! U/ I( d7 I- o0 ^  B3 x9 C
  也就是说要实现一个Interceptor,以供在连接点时触发。Spring中采用了AOP联盟(AOP Alliance)的通用AOP接口(接口定义位aopalliance.jar)。这里我们采用aopalliance.jar中定义的MethodInterceptor作为我们的Advice实现接口。那么我们上节例子中的处理方式应实现为如下Interceptor:
5 y) q4 s' l- Y: Z  K+ h: E; mpackage test.aop.spring; 0 v! y4 e0 q+ \. K
import java.util.logging.Logger; 7 N8 B" t' g7 E2 r3 Q$ T
import org.aopalliance.intercept.MethodInterceptor;
7 F2 r: ]0 }4 j  Uimport org.aopalliance.intercept.MethodInvocation;

/**
/ q. x: B; Y" {' w+ y" z7 u* @author xkf 4 o' V6 ^5 F$ E1 S$ J) ?1 r
**/ 9 H2 D( {( e" F4 h  _0 N
public class LockInterceptor implements MethodInterceptor { ( ?& f; r8 a; ~4 X( l
private Logger logger = Logger.getLogger(this.getClass().getName());
1 W4 L9 k5 q7 Hpublic Object invoke(MethodInvocation invocation) throws Throwable {
$ i; i- @' x2 {/ v$ S+ _( F// TODO Auto-generated method stub
0 y- o7 j8 R" W* L* W# G9 Ilock(); $ }) H* L8 _0 w( K$ p- _
Object ret= invocation.proceed(); 4 v6 R- |7 ]' P
unlock();
7 \! m6 A  a! S& z5 A% ^return ret;
" B* B7 Z* |# L. a2 v7 }} ' _2 |7 m* H4 A% m, [4 f  @& ]
private void lock(){
! F0 k8 ]- n* m# ?logger.info("lock domain object...");
2 t( y" F, n- ?8 i  @( o% o0 `}
$ y- u% D+ m# h+ [0 k8 pprivate void unlock(){ . y: k3 c# e- p- f
logger.info("unlock domain object...");
% M& i7 _0 R( ]# N* V+ n4 K}
3 L, I2 Y# g3 i}
9 ^4 q7 B2 S' g, M$ O  实现后,对应的Interceptor实现类在配置文件中的体现如下: % [% R; I4 e* g  p4 v0 r( u! @
  <bean id="MyInterceptor" class="test.aop.spring.LockInterceptor"/>
+ L( Q" F3 ~7 `2 W! ]/ N7 m  最后,我们还需要定义一个Spring AOP ProxyFactory用于加载执行AOP组件,并且需要将Advice通过IOC的方式注入到接口以及实现类。
: z# s; F$ I8 [8 @  对应的配置文件应如下配置从而实现这些内容: 8 ?4 n3 J! S% x' Q* D) c/ u
<bean id="myAOPProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
2 A: _$ h$ F$ z4 V* G, |8 T! D, B<property name="proxyInterfaces">
8 c9 X7 f- B, b1 A% o2 ~<value>test.aop.spring.DomainObjDAO</value>
+ h# S. g: ]  z9 M6 B' B</property>
  F. h# [2 `7 V6 t. U: z6 f( `<property name="target"> # m+ _: w, P' P; D
<ref local="impl" /> " ^7 n( ?  I2 `3 N* m0 K
</property>
0 p% y$ Y% }6 ^0 s% Q5 P. P<property name="interceptorNames"> ' C8 F" I* B, [
<value>myPointcutAdvisor</value>
5 W: s9 s2 m2 L: P% M7 X</property> 8 u9 C; M; v3 o9 g3 @" q
</bean>
  Z# P* B+ s% m: p! K<bean id="impl" class="test.aop.spring.DomainObjDAOImpl"/>
# O/ V( f; `7 b+ Z/ L* j万事大吉!写一个TestCase来看一下运行结果: 3 }. h( n9 q) e7 m+ |
package test.aop.spring;

import junit.framework.TestCase;
4 k/ g% ?" Y% m* simport org.springframework.context.ApplicationContext;
' q" i+ t/ A! rimport org.springframework.context.support.FileSystemXmlApplicationContext;

/** . B1 d+ C* B$ f; Z% X# N! v
* @author xkf   X. n* M# x" k
*/
1 `9 ?. c& p2 C. _5 [public class SpringTestCase extends TestCase { 8 p8 [# v' d2 z1 R
DomainObjDAO test=null;

protected void setUp() throws Exception { 1 }( X7 l/ v- c" k2 F7 t8 R8 f
super.setUp(); ! o# h1 G* @. k
ApplicationContext ctx=new FileSystemXmlApplicationContext("test/Bean.xml");
; B: t4 {7 v% Ptest = (DomainObjDAO) ctx.getBean("myAOPProxy"); # @. w, L2 [: \* q/ j9 L3 g! E+ k
}

protected void tearDown() throws Exception { : r5 X, v- k% G; d/ k6 R( B3 S  \4 v5 k
super.tearDown();
3 }. s' v. P; O8 r8 W, T} - w0 o. j( d4 J! l1 K+ P' m
public void testSave(){ ! h/ b- b0 N. }0 l
test.save(); 7 l: U4 g2 U" g  ?$ b
}
& E3 v7 S0 P, {0 f, G  V} * @, P: v5 C9 ^' K' m9 L$ w" [
运行结果如下:
0 ]1 w8 ^% r$ F5 ]7 {6 J信息: Creating shared instance of singleton bean ''MyInterceptor''
- {$ ~! R* L# u4 D2004-12-7 23:50:11 test.aop.spring.LockInterceptor lock
) J" X; G, L7 ?0 x信息: lock domain object...
# j; n1 G" {4 J/ M* L0 }- isaving domain object......
% G& o8 I' k9 \3 T3 b/ f2004-12-7 23:50:11 test.aop.spring.LockInterceptor unlock
( C. D+ u+ n& ~' C! m+ }信息: unlock domain object...

  OK!至此,我们已经探讨了AOP动态代理的实现以及其在Spring中的应用,接下来的Blog中我将会关注Spring中事务以及持久化的实现。

8 I) j; u8 _* m( X

科帮网 1、本主题所有言论和图片纯属会员个人意见,与本社区立场无关
2、本站所有主题由该帖子作者发表,该帖子作者与科帮网享有帖子相关版权
3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和科帮网的同意
4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
7、科帮网管理员和版主有权不事先通知发贴者而删除本文


JAVA爱好者①群:JAVA爱好者① JAVA爱好者②群:JAVA爱好者② JAVA爱好者③ : JAVA爱好者③

快速回复
您需要登录后才可以回帖 登录 | 立即注册

   

关闭

站长推荐上一条 /1 下一条

发布主题 快速回复 返回列表 联系我们 官方QQ群 科帮网手机客户端
快速回复 返回顶部 返回列表