Spring的AOP

2013-3-6 雨辰 游戏架构

Spring的AOP是上面代理模式的深入。使用Spring AOP,开发者无需实现业务逻辑对象工厂,无需实现代理工厂,这两个工厂都由Spring容器充当。Spring AOP不仅允许使用XML文件配置目标方法,ProxyHandler也允许使用依赖注入管理,Spring AOP提供了更多灵活的选择。
在下面Spring AOP的示例中,InvocationHandler采用动态配置,需要增加的方法也采用动态配置,一个目标对象可以有多个拦截器(类似于代理模式中的代理处理器)。
下面是原始的目标对象:
//目标对象的接口
public interface Person
{
//该接口声明了两个方法
void info();
void run();
}
下面是原始目标对象的实现类,实现类的代码如下:
//目标对象的实现类,实现类实现Person接口
public class PersonImpl implements Person
{
//两个成员属性
private String name;
private int age;
//name属性的 setter方法
public void setName(String name)
{
this.name = name;
}
//age属性的setter方法
public void setAge(int age)
{
this.age = age;
}
//info方法,该方法仅仅在控制台打印一行字符串
public void info()
{
System.out.println("我的名字是: " + name + " , 今年年龄为: " + age);
}
//run方法,该方法也在控制台打印一行字符串。
public void run()
{
if (age < 45)
{
System.out.println("我还年轻,奔跑迅速...");
}
else
{
System.out.println("我年老体弱,只能慢跑...");
}
}
}
该Person实例将由Spring容器负责产生和管理,name属性和age属性也采用依赖注入管理。
为了充分展示Spring AOP的功能,此处为Person对象创建三个拦截器。第一个拦截器是调用方法前的拦截器,代码如下:
//调用目标方法前的拦截器,拦截器实现MethodBeforeAdvice接口
public class MyBeforeAdvice implements MethodBeforeAdvice
{
//实现MethodBeforeAdvice接口,必须实现before方法,该方法将在目标
//方法调用之前,自动被调用。
public void before(Method m, Object[] args, Object target) throws Throwable
{
System.out.println("方法调用之前...");
System.out.println("下面是方法调用的信息:");
System.out.println("所执行的方法是:" + m);
System.out.println("调用方法的参数是:" + args);
System.out.println("目标对象是:" + target);
}
}
第二个拦截器是方法调用后的拦截器,该拦截器将在方法调用结束后自动被调用,拦截器代码如下:
//调用目标方法后的拦截器,该拦截器实现AfterReturningAdvice接口
public class MyAfterAdvice implements AfterReturningAdvice
{
//实现AfterReturningAdvice接口必须实现afterReturning方法,该方法将在目标方法
//调用结束后,自动被调用。
public void afterReturning(Object returnValue, Method m, Object[] args, Object target)throws Throwable
{
System.out.println("方法调用结束...");
System.out.println("目标方法的返回值是 : " + returnValue);
System.out.println("目标方法是 : " + m);
System.out.println("目标方法的参数是 : " + args);
System.out.println("目标对象是 : " + target);
}
}
第三个拦截器是是Around拦截器,该拦截器既可以在目标方法之前调用,也可以在目标方法调用之后被调用。下面是Around拦截器的代码:
//Around拦截器实现MethodInterceptor接口
public class MyAroundInterceptor implements MethodInterceptor
{
//实现MethodInterceptor接口必须实现invoke方法
public Object invoke(MethodInvocation invocation) throws Throwable
{
//调用目标方法之前执行的动作
System.out.println("调用方法之前: invocation对象:[" + invocation + "]");
//调用目标方法
Object rval = invocation.proceed();
//调用目标方法之后执行的动作
System.out.println("调用结束...");
return rval;
}
}
利用Spring AOP框架,实现之前的代理模式相当简单。只需要实现对应的拦截器即可,无需创建自己的代理工厂,只需采用Spring容器作为代理工厂。下面在Spring配置文件中配置目标bean,以及拦截器。
下面是Spring配置文件的代码:
<?xml version="1.0" encoding="gb2312"?>
<!-- Spring配置文件的文件头-->
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<!-- Spring配置文件的根元素-->
<beans>
<!-- 配置目标对象-->
<bean id="personTarget" class="lee.PersonImpl">
<!-- 为目标对象注入name属性值-->
<property name="name">
<value>Wawa</value>
</property>
<!-- 为目标对象注入age属性值-->
<property name="age">
<value>51</value>
</property>
</bean>
<!-- 第一个拦截器-->
<bean id="myAdvice" class="lee.MyBeforeAdvice"/>
<!-- 第二个拦截器-->
<bean id="myAroundInterceptor" class="lee.MyAroundInterceptor"/>
<!-- 将拦截器包装成Advisor,该对象还确定代理对怎样的方法增加处理-->
<bean id="runAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- advice属性确定处理bean-->
<property name="advice">
<!-- 此处的处理bean定义采用嵌套bean,也可引用容器的另一个bean-->
<bean class="lee.MyAfterAdvice"/>
</property>
<!-- patterns确定正则表达式模式-->
<property name="patterns">
<list>
<!-- 确定正则表达式列表-->
<value>.*run.*</value>
</list>
</property>
</bean>
<!-- 使用ProxyFactoryBean 产生代理对象-->
<bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 代理对象所实现的接口-->
<property name="proxyInterfaces">
<value>lee.Person</value>
</property>
<!-- 设置目标对象-->
<property name="target">
<ref local="personTarget"/> 
</property>
<!-- 代理对象所使用的拦截器-->
<property name="interceptorNames">
<list>
<value>runAdvisor</value>
<value>myAdvice</value>
<value>myAroundInterceptor</value>
</list>
</property>
</bean>
</beans>
该配置文件使用ProxyFactoryBean来生成代理对象,配置ProxyFactoryBean工厂bean时,指定了target属性,该属性值就是目标对象,该属性值为personTarget,指定代理的目标对象为personTarget。通过interceptorNames属性确定代理需要的拦截器,拦截器可以是普通的Advice,普通Advice将对目标对象的所有方法起作用,拦截器也可以是Advisor,Advisor是Advice和切面的组合,用于确定目标对象的哪些方法需要增加处理,以及怎样的处理。在上面的配置文件中,使用了三个拦截器,其中myAdvice、myAroundInterceptor都是普通Advice,它们将对目标对象的所有方法起作用。而runAdvisor则使用了正则表达式切面,匹配run方法,即该拦截器只对目标对象的run方法起作用。

下面是测试代理的主程序:
public class BeanTest
{
public static void main(String[] args)throws Exception
{
//创建Spring容器
ApplicationContext ctx = new FileSystemXmlApplicationContext("bean.xml");
//获取代理对象
Person p = (Person)ctx.getBean("person");
//执行info方法
p.info();
System.out.println("===========================================");
//执行run方法
p.run();
}
}
下面是程序的执行结果:
方法调用之前...
下面是方法调用的信息:
所执行的方法是:public abstract void lee.Person.info()
调用方法的参数是:null
目标对象是:lee.PersonImpl@b23210
调用方法之前: invocation对象:[invocation: method 'info', arguments
[]; target is of class [lee.PersonImpl]]
我的名字是: Wawa , 今年年龄为: 51
调用结束...
===========================================
方法调用之前...
下面是方法调用的信息:
所执行的方法是:public abstract void lee.Person.run()
调用方法的参数是:null
目标对象是:lee.PersonImpl@b23210
调用方法之前: invocation对象:[invocation: method 'run', arguments [
]; target is of class [lee.PersonImpl]]
我年老体弱,只能慢跑...
调用结束...
方法调用结束...
目标方法的返回值是 : null
目标方法是 : public abstract void lee.Person.run()
目标方法的参数是 : null
目标对象是 : lee.PersonImpl@b23210
程序的执行结果中一行“=”用于区分两次调用的方法。在调用info方法时,只有myAdvice和myAroundInterceptor两个拦截器起作用,调用run方法时候,三个拦截器都起作用了。

通过上面的介绍,可看出Spring的AOP框架是对代理模式简化,并拓展了代理模式的使用。
Spring AOP是Spring声明式事务的基础。了解Spring AOP对深入理解Spring的声明式事务管理是非常有好处的。Spring AOP还可以完成很多功能,例如基于AOP的权限检查。

标签: 游戏业务架构设计 技术问题

评论:

accentskosher
2021-06-13 13:14
<a href="https://www.eleikoitalia.com/aldo-romeu-torba-torebkid">aldo romeu torba</a> <a href="https://www.afolkmusician.com/xs-max-case-with-card-holder-casec">xs max case with card holder</a> <a href="https://www.sucrehoteles.com/dune-roze-handtas-tassenb">dune roze handtas</a> <a href="https://www.ponosolution.com/pouzdro-mate-barely-there-iphone-se-pouzdroe">pouzdro mate barely there iphone se</a> <a href="https://www.ribbitsalon.com/hush-jumper-%C5%A1aty-satyc">hush jumper 拧aty</a> <a href="https://www.buyinaustintx.com/philadelphia-eagles-sideline-cappello-cappelloa">philadelphia eagles sideline cappello</a>
accentskosher https://www.accentskosher.com/
windowfilmnow
2021-05-29 17:44
<a href="https://www.aiawyoming.com/iphone-se-crossbody-case-casec">iphone se crossbody case</a> <a href="https://www.wikistrea.com/rood-shoulder-zak-supreme-tassenb">rood shoulder zak supreme</a> <a href="https://www.ascreenworks.com/iphone-6-front-a-back-pouzdro-pouzdroe">iphone 6 front a back pouzdro</a> <a href="https://www.justaccord.com/new-look-asymmetric-%C5%A1aty-satyc">new look asymmetric 拧aty</a> <a href="https://www.ericrcourtney.com/cowgirl-cappelli-amazon-cappelloa">cowgirl cappelli amazon</a> <a href="https://www.pepperlilly.com/light-blue-wedding-sandals-bootsa">light blue wedding sandals</a>
windowfilmnow https://www.windowfilmnow.com/
hopsgrapes
2021-05-26 21:42
<a href="http://www.bajoecolodge.com/nba-christmas-buty-tenisc">nba christmas buty</a> <a href="http://www.jokkit.com/gull-glitter-long-sleeve-kjole-kjoleb">gull glitter long sleeve kjole</a> <a href="http://www.depomachine.com/stylish-professional-rucksack-tasched">stylish professional rucksack</a> <a href="http://www.jaygeldhof.com/magliette-psg-jordan-tutab">magliette psg jordan</a> <a href="http://www.populerbahis.com/nike-kyrie-flytrap-2-rouge-chaussures1">nike kyrie flytrap 2 rouge</a> <a href="http://www.dhactun.com/ultra-boost-2.0-limited-oro-medal-zapatos1">ultra boost 2.0 limited oro medal</a>
hopsgrapes http://www.hopsgrapes.com/
prettysocial
2021-05-23 18:09
<a href="https://www.elleve.net/mcm-bag-womens-bagsa">mcm bag womens</a> <a href="https://www.halfwitwines.net/jordan-concord-11-hat-hatb">jordan concord 11 hat</a> <a href="https://www.oetopia.net/adidas-golden-knights-71-william-karlsson-purple-authentic-fights-cancer-stitched-nhl-jersey-jerseyb">adidas golden knights 71 william karlsson purple authentic fights cancer stitched nhl jersey</a> <a href="https://www.playper.net/jordan-10-red-blue-shoes3">jordan 10 red blue</a> <a href="https://www.acutechpiping.net/adidas-bugs-bunny-t-shirt-shirtb">adidas bugs bunny t shirt</a> <a href="https://www.warmte.net/iphone-xs-case-speck-casec">iphone xs case speck</a>
prettysocial https://www.prettysocial.net/
vefvistun
2021-05-06 15:51
<a href="http://www.eligro.net/zara-stiefel-kinder-stiefeld">zara stiefel kinder</a> <a href="http://www.carloscurbelo.net/zwart-dekking-iphone-7-hoesjea">zwart dekking iphone 7</a> <a href="http://www.autovibe.net/adidas-blues-55-colton-parayko-purple-authentic-fights-cancer-stitched-nhl-jersey-jerseyc">adidas blues 55 colton parayko purple authentic fights cancer stitched nhl jersey</a> <a href="http://www.tinacatherine.net/3-fold-sk%C3%B3rzany-portfel-torebkid">3 fold sk贸rzany portfel</a> <a href="http://www.sqlsteve.net/iphone-8-plus-rose-red-case-casec">iphone 8 plus rose red case</a> <a href="http://www.jetoxco.net/medium-leer-rugzak-tassenb">medium leer rugzak</a>
[url=http://www.vefvistun.net/]vefvistun[/url]
pmlambert
2021-05-04 10:10
<a href="http://www.jazzvoc.com/damen-small-rucksack-handtaschen-tasched">damen small rucksack handtaschen</a> <a href="http://www.diibdesign.com/felpa-nike-sb-uomo-tutab">felpa nike sb uomo</a> <a href="http://www.trentcpas.com/95-ultra-jacquard-noir-chaussures1">95 ultra jacquard noir</a> <a href="http://www.flixscout.com/blanco-gum-adidas-nmd-zapatos1">blanco gum adidas nmd</a> <a href="http://www.vegasbunboy.com/milwaukee-brewers-tutti-bianca-collection-59fifty-berretto-cappellod">milwaukee brewers tutti bianca collection 59fifty berretto</a> <a href="http://www.anelaflores.com/adidas-ultra-boost-salmon-r%C3%B3zsasz%C3%ADn-sneaker5">adidas ultra boost salmon r贸zsasz铆n</a>
pmlambert http://www.pmlambert.com/

发表评论:

朱文华 joyimp|@2011-2022 京ICP备16030765号-2