Spring AOP的实现机制(三)---@AspectJ形式的Spring AOP和基于Schema的AOP

来源:互联网 发布:东方网络最新公告 编辑:程序博客网 时间:2024/06/05 08:07
<span style="font-size:18px;">1、@AspectJ形式的Spring AOP  @AspectJ代表一种定义Aspect的风格,它让我们能够以POJO的形式定义Aspect,没有其它接口限制。唯一需要的,就是使用相应的注解标注这些Aspect定义的POJO类。之后SpringAOP会根据标注的注解搜索这些Aspect定义类,  然后将其织入系统。  其实SpringAOP只使用AspectJ的类库进行Pointcut的解析和匹配,最终的实现机制还是Spring AOP最初的架构,也就是使用代理模式处理横切逻辑的织入。  定义一个切面类的一般方法为:  使用@Aspect标注Aspect类,@Pointcut的注解指定Pointcut定义,@Around等注解指定哪些方法定义了相应的Advice逻辑  通过一个来说明  @Aspect  public class PerformanceTraceAspect {private final Log logger=LogFactory.getLog(PerformanceTraceAspect.class);@Pointcut("execution(public void *.method1())||execution(public void *.method2())")public void pointcutName(){}@Around("pointcutName()")public Object performanceTrace(ProceedingJoinPoint joinpoint)throws Throwable{try{System.out.println("start.......");return joinpoint.proceed();}finally{System.out.println("stop......");if(logger.isInfoEnabled()){logger.info("PT in method["+joinpoint.getSignature().getName()+"]>>>>>");}}}  }    public class Foo {public void method1(){System.out.println("method1 execution");}public void method2(){System.out.println("method2 execution");}public void method3(){System.out.println("method3 execution");}public void doSomething(String str){System.out.println(str+"do something");} }  (1)通过编程方式织入: public class aspectProgrammingTest {@Testpublic void test() {AspectJProxyFactory weaver=new AspectJProxyFactory();weaver.setProxyTargetClass(true);weaver.setTarget(new Foo());weaver.addAspect(PerformanceTraceAspect.class);Object proxy=weaver.getProxy();((Foo)proxy).method1();((Foo)proxy).method2();} }  通过自动代理织入 针对@AspectJ风格的AOP,Spring AOP专门提供了一个AutoProxyCreator实现类进行自动代理,以免去过多编码和配置的工作, 只需要在IoC容器的配置文件中注册一下AnnotationAwareAspectJAutoProxyCreator就可以了。 实现如下: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"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.5.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context-2.5.xsd        http://www.springframework.org/schema/tx        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">        <!-- 基于XSD的配置方式 -->        <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy><!-- 基于DTD的配置方式 --><!-- <beanclass="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"><property name="proxyTargetClass" value="true"></property></bean> --><bean id="performanceTraceAspect" class="aop.spring.aspectTest.YourAspect"/><bean id="target" class="aop.spring.aspect.Foo"/></beans>测试类:public class aspectXmlTest {@Testpublic void test() {ApplicationContext ctx=new ClassPathXmlApplicationContext("/beans.xml");Object proxy=ctx.getBean("target");((Foo)proxy).method1();((Foo)proxy).method2();((Foo)proxy).doSomething("zhsi...");}}2、基于Schema的AOP新的基于Schema的AOP配置方式,针对Pointcut、Advisor以及Aspect等概念提供了独立的配置元素,所有这些配置元素都包含在统一的配置元素中,即<aop:config><aop:config>有三个子元素,分别是<aop:pointcut>、<aop:advisor>、 <aop:aspect>.它们三个必须按照顺序进行配置实现的例子如下:基于Schema的Advice声明也分为两部分,即Advice的定义和Advice的到容器的配置Advice的定义如下:public class SchemaBaseAspect {public void doBefore(JoinPoint jp){System.out.println("before method[ "+jp.getSignature().getName()+" ] execution");}public void doAfterReturning(JoinPoint jp){System.out.println("method["+jp.getSignature().getName()+"]completed successfully");}public Object doAround(ProceedingJoinPoint pjp) throws Throwable{System.out.println("around start.....");Object reVal=pjp.proceed();System.out.println("around end....");return reVal;}}配置声明如下:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"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.5.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context-2.5.xsd        http://www.springframework.org/schema/tx        http://www.springframework.org/schema/tx/spring-tx-2.5.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"><bean id="schemaBaseAspect" class="com.aop.spring.SchemaBaseAspect"></bean><aop:config><aop:aspect id="myAspect" ref="schemaBaseAspect" order="2"><aop:pointcut id="privatepoint" expression="execution(public void *.doSth())"></aop:pointcut><aop:before pointcut-ref="privatepoint" method="doBefore"></aop:before><aop:after-returning pointcut-ref="privatepoint" method="doAfterReturning"></aop:after-returning><aop:around pointcut-ref="privatepoint" method="doAround"></aop:around></aop:aspect></aop:config><bean id="targetFoo" class="com.aop.spring.TargetFoo"></bean></beans>测试类如下:public class XSDTest {@Testpublic void test() {ApplicationContext ctx=new ClassPathXmlApplicationContext("beans1.xml");TargetFoo f=(TargetFoo) ctx.getBean("targetFoo");f.doSth();}}对于Introduction类型的advice有其独特的实现方式,这里就不再详细介绍了。到目前为止,我们接触了如下三种Spring AOP的使用方式(1) Spring AOP 1.x 版本发布的基于接口定义的Advice声明方式。这种方式的特点是,各种类型的Advice定义需要实现特定的接口,Advice的管理可以通过IoC容器或者直接编程来进行。我们将其称为第一代Spring AOP(2)@AspectJ形式的AOP是在Spring2.0发布之后新增加的一种Spring AOP使用方式。在这种方式中,我们只需要以POJO的形式声明相应的Aspect和Advice,然后通过相应的注解标注一下即可,(3)基于Schema的AOP也是在Spring2.0发布之后增加的Spring AOP使用方式,它融合了第一代Spring AOP和@AspectJ 形式的优点,不但完全支持第一代Spring AOP的配置需求,而且在@Aspect形式的AOP的基础之上进行了改装:我们依然可以通过POJO声明Aspect和Advice定义,不过,通过相应注解表达的各种信息,转移到了XSD形式的容器配置文件中。  对于如何在这三种方式之间进行选择,应该依照当前应用环境、各种工具支持、整体团队对各种方式的熟悉程度等不同情况来权衡利弊,最终决定一种合适的方式。  目前对于我来说,我还只是在学习阶段,所以对于选择哪一种Spring AOP 方式我还不是有所体会。     what do you want?  </span>

0 0
原创粉丝点击