首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

AOP学习札记

2012-09-09 
AOP学习笔记1、依赖配置方式测试方法:public void test1() {??String filePath System.getProperty(user

AOP学习笔记

1、依赖配置方式

测试方法:

public void test1() {
??String filePath = System.getProperty("user.dir") + File.separator + "src/com/dmeo/aop"
???+ File.separator + "spring.xml";
??BeanFactory factory = new XmlBeanFactory(new FileSystemResource(filePath));

??Shopping shopping = null;
??System.out.println("不使用任何通知");
??shopping = (Shopping) factory.getBean("shoppingImpl");
??shopping.buySomething("something");
??//??? shopping.buyAnything("anything");

?

??System.out.println("使用前置通知");
??shopping = (Shopping) factory.getBean("welcomeAdviceShop");
??shopping.buySomething("type2");
??shopping.buyAnything("anything");
?}

?

spring.xml

<bean id="welcomeAdvice" />
?<bean id="welcomeAdviceShop"
??/>
??</property>
??
??<!-- 以下属性没有的话不会出错,interceptorNames如果没有配置,target的方法就不会被拦截 -->
??<property name="proxyInterfaces">
???<value>com.dmeo.aop.Shopping</value>
??</property>
??<property name="interceptorNames">
???<list>
????<value>welcomeAdvice</value>
???</list>
??</property>
?</bean>

?

2.不干涉原先的bean配置,AOP真正的强悍啊,可以用来测试,添加日志等

1).单个通知

<beans xmlns="http://www.springframework.org/schema/beans"
?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
?xmlns:tx="http://www.springframework.org/schema/tx"
?xmlns:aop="http://www.springframework.org/schema/aop"
?xmlns:jee="http://www.springframework.org/schema/jee"
?xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
?http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
?http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
?http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">

?<bean id="customer" />
??</property>
?</bean>

?<bean id="welcomeAdvice" />

?<aop:config>
??<aop:pointcut id="serviceOperation-before"
???expression="execution(* com.dmeo.aop.*.*(..))" />
??<aop:advisor pointcut-ref="serviceOperation-before"
???advice-ref="welcomeAdvice" />
?</aop:config>

注意前面的bean的引用以及AOP的配置。

?

上面的配置只能够对切面(方法)的一种行为进行拦截,比如WelcomeAdvice实现MethodBeforeAdvice,就只能在切点调用之前进行通知(前置通知)。(后置通知 AfterReturningAdvice、环绕通知 MethodInterceptor、异常通知 ThrowsAdvice)

?

下面给出对切面的所有行为进行拦截通知。

?

2).多个通知一起拦截

<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/beans
??????????? http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
??????????? http://www.springframework.org/schema/aop
??????????? http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
?default-autowire="autodetect">

?<aop:config>
??<aop:aspect id="TestAspect" ref="aspectBean">
???<!--配置com.dmeo.aop2包下所有类或接口的所有方法-->
???<aop:pointcut id="businessService"
????expression="execution(* com.dmeo.aop2.*.*(..))" />
????
???<aop:before pointcut-ref="businessService"????method="doBefore" />
???<aop:after pointcut-ref="businessService" method="doAfter" />
???<aop:around pointcut-ref="businessService"????method="doAround" />
???<aop:after-throwing pointcut-ref="businessService"???method="doThrowing" throwing="ex" />
??</aop:aspect>
?</aop:config>

?<bean id="aspectBean" />
?<bean id="aService" class="com.dmeo.aop2.BServiceImpl"></bean>
</beans>

?

测试类:

public static void main(String[] args) {
??String filePath = "com/dmeo/aop2/spring.xml";

?// 必须得用ApplicationContext
??ApplicationContext factory = new ClassPathXmlApplicationContext(filePath);

??aService = (AService) factory.getBean("aService");
??bService = (BServiceImpl) factory.getBean("bService");

??testThrow();
?}

?public static void testCall() {
??System.out.println("Spring AOP test");
??aService.fooA("test fooA");
??aService.barA();
??bService.fooB();
??bService.barB("test barB", 0);
?}

?public static void testThrow() {
??try {
???bService.barB("call barB", 1);
??} catch (IllegalArgumentException e) {
??}
?}

?

详细代码见附件~~~

?

重点说明:

《Spring参考手册》中定义了以下几个AOP的重要概念,结合以上代码分析如下:

切面(Aspect) :官方的抽象定义为“一个关注点的模块化,这个关注点可能会横切多个对象”,在本例中,“切面”就是类TestAspect所关注的具体行为,例如,AServiceImpl.barA()的调用就是切面TestAspect所关注的行为之一。“切面”在ApplicationContext中<aop:aspect>来配置。 连接点(Joinpoint) :程序执行过程中的某一行为,例如,AServiceImpl.barA()的调用或者BServiceImpl.barB(String _msg, int _type)抛出异常等行为。 通知(Advice) :“切面”对于某个“连接点”所产生的动作,例如,TestAspect中对com.spring.service包下所有类的方法进行日志记录的动作就是一个Advice。其中,一个“切面”可以包含多个“Advice”,例如TestAspect 切入点(Pointcut) :匹配连接点的断言,在AOP中通知和一个切入点表达式关联。例如,TestAspect中的所有通知所关注的连接点,都由切入点表达式execution(* com.spring.service.*.*(..))来决定 目标对象(Target Object) :被一个或者多个切面所通知的对象。例如,AServcieImpl和BServiceImpl,当然在实际运行时,Spring AOP采用代理实现,实际AOP操作的是TargetObject的代理对象。 AOP代理(AOP Proxy) 在Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。默认情况下,TargetObject实现了接口时,则采用JDK动态代理,例如,AServiceImpl;反之,采用CGLIB代理,例如,BServiceImpl。强制使用CGLIB代理需要将 <aop:config>proxy-target-class 属性设为true

?execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

modifiers-pattern:方法的操作权限

ret-type-pattern:返回值

declaring-type-pattern:方法所在的包

name-pattern:方法名

parm-pattern:参数名

throws-pattern:异常

其中,除ret-type-pattern和name-pattern之外,其他都是可选的。上例中,execution(* com.spring.service.*.*(..))表示com.spring.service包下,返回值为任意类型;方法名任意;参数不作限制的所有方法。

热点排行