基于AspectJ的AOP编程已经可以满足我们的编程需要,为什么这里还要做一套基于Schema的逻辑呢,这里有两个理由:
1.Java语言直到5.0才支持注解功能,所以在5.0之前的版本如果也想体验到AspectJ的便利,就需要使用特殊的方法。
2.AspectJ无法针对切面Advisor编程,但是Schema可以。
前置增强:
public class AdviceMethods { public void preGreeting() { System.out.println("--how are you--"); } }
<bean id="naiveWaiter" class="com.firethewhole.maventest08.NaiveWaiter"/> <bean id="naughtyWaiter" class="com.firethewhole.maventest08.NaughtyWaiter"/> <bean id="adviceMethods" class="com.firethewhole.maventest08.schema.AdviceMethods"/> <bean id="smartSeller" class="com.firethewhole.maventest08.SmartSeller"/> <aop:config proxy-target-class="true"> <aop:aspect ref="adviceMethods"> <aop:pointcut expression="target(com.firethewhole.maventest08.NaiveWaiter) and execution(* greetTo(..))" id="greetToPointcut"/> <aop:before method="preGreeting" pointcut-ref="greetToPointcut"/> </aop:aspect> </aop:config>
测试代码:
public class SchemaProxyTest { public static void main(String[] args) { String configLocation = "com/firethewhole/maventest08/schema/beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocation); Waiter naiveWaiter = (Waiter) ctx.getBean("naiveWaiter"); Waiter naughtyWaiter = (Waiter) ctx.getBean("naughtyWaiter"); naiveWaiter.greetTo("John"); naughtyWaiter.greetTo("John"); } }
输出:
--how are you--
NaiveWaiter.greet to John
NaughtyWaiter: greet to John
我们并没有使用注解或者AspectJ的相关功能,只是在XML配置类相关的Bean和<aop:config>,也达到了相同的效果。
后置增强:
<aop:after-returning method="afterReturning" pointcut="target(com.firethewhole.maventest08.SmartSeller)" returning="retVal"/>
可以看到我们依然可以在配置文件中绑定返回值。
环绕增强:
<aop:around method="aroundMethod" pointcut="execution(* serveTo(..)) and target(com.firethewhole.maventest08.Waiter)"/>
环绕增强可以绑定连接点信息
public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable { System.out.println("开始进入方法:" + pjp.getTarget().getClass()); System.out.println("参数为:" + pjp.getArgs()[0]); pjp.proceed(); System.out.println("开始退出方法:" + pjp.getTarget().getClass()); }
抛出异常增强:
<aop:after-throwing method="afterThrowingMethod" pointcut="execution(* checkBill(..)) and target(com.firethewhole.maventest08.SmartSeller)" throwing="iae"/>
public void afterThrowingMethod(IllegalArgumentException iae) { System.out.println("抛出异常:" + iae.getMessage()); }
这里绑定类异常信息。
Final增强:
<aop:after method="afterMethod" pointcut="execution(* com..*.Waiter.greetTo(..))"/>
无论是否有异常都会执行。
引介增强:
<aop:declare-parents types-matching="com.firethewhole.maventest08.Waiter+" implement-interface="com.firethewhole.maventest08.Seller" default-impl="com.firethewhole.maventest08.SmartSeller"/>
增强绑定参数:
<aop:before method="bindParams" pointcut="target(com.firethewhole.maventest08.NaiveWaiter) and args(name,num,..)"/>
public void bindParams(int num, String name) { System.out.println("-----bindParams-----"); System.out.println("name:" + name); System.out.println("num:" + num); System.out.println("-----bindParams-----"); }
public class SchemaProxyTest { public static void main(String[] args) { String configLocation = "com/firethewhole/maventest08/schema/beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configLocation); Waiter naiveWaiter = (Waiter) ctx.getBean("naiveWaiter"); ((NaiveWaiter)naiveWaiter).smile("John", 2); } }
输出:
-----bindParams-----
name:John
num:2
-----bindParams-----
NaiveWaiter.smile to John 2 times