zoukankan      html  css  js  c++  java
  • 浅谈spring——注解配置(九)

    spring定义一个切面是件麻烦的事情,需要实现专门的接口,还要进行一些较为复杂的配置,有没有较为简单的方法???

    @AspectJ注解可以很容易定义一个切面,且不需要实现任何的接口。缺点是对JDK的版本有限制,要求是5.0以上

    当然对于不足5.0的版本,可以通过Schema的配置定义切面,方便程度和@AspectJ相差无几。


    无论是基于XML配置的AOP还是基于@AspectJ注解的AOP,只是在表达方式有所不同,底层都是采用动态代理技术(JDK代理或CGLib代理)。


    注解是代码的附属信息,它遵循一个原则:注解不能直接干扰程序代码的运行,无论是增加或删除注解,代码都能正常运行。java语言解释器会忽略这些注解,而由第三方工具对注解进行解析,从而达到间接控制程序代码的运行,它们通过java反射机制读取注解的信息。


    Pointcut和Advice分别表切点和增强,并用Advisor将两者整体为切面,@AspectJ则是采用注解的方式来描述切点、增强,两者只是表述上有所不同,本质是一样的。


    代码示例:

    切面

    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    @Aspect
    public class PreGreetingAspect{
    	@Before("execution(* greetTo(..))")
    	public void beforeGreeting(){
    		System.out.println("How are you");
    	}
    }
    

    a.  PreGreetingAspect类定义处,标注了@Aspect注解,表示其为一个切面。

    b.  beforeGreeting方法上,Before表示是前置增强;execution(* greetTo(..))表示一个切点表达式,在目标类的greetTo()方法上织入增强,greetTo方法可以带任意入参和任意返回值。

    c.  beforeGreeting方法体,表示具体的横切逻辑。

    PreGreetingAspect类通过注解和代码,将切点、增强类型、增强逻辑糅合到一个类中。


    配置文件

     <aop:aspectj-autoproxy/>
    	//目标bean
    	<bean id="waiter" class="com.baobaotao.NaiveWaiter" />
    	//采用@AspectJ注解的切面类
    	<bean class="com.aspectj.example.PreGreetingAspect" />	
    	//自动代理创建器,自动将@AspectJ切面类织入到目标Bean中
    	<bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>


    AspectJ的切点表达式由关键字和操作参数组成。如execution(* greetTo(..))

    execution为关键字(ps:表示目标类执行某一方法)

    * greetTo(..)为操作参数(ps:表示目标方法的匹配模式串)


    目前spring支持9个@AspectJ切点表达式函数,他们用不同的方式描述目标类的连接点,大致分为4种类型:

    1)方法切点函数:通过描述目标类方法信息定义连接点,如execution

    2)方法入参切点函数:通过描述目标类方法入参的信息定义连接点

    3)目标类切点函数:通过描述目标类类型信息定义连接点

    4)代理类切点函数:通过描述目标类的代理类的信息定义连接点


    增强类型:

    @Before 前置增强

    @AfterReturning 后置增强

    @Around 环绕增强

    @AfterThrowing 抛出异常的增强

    @DeclareParents 引介增强

    与xml形式的基本一致,只是换了种表达方式,采用了注解的形式来描述。


    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    对于不满足JDK5.0的项目,只能望@AspectJ而兴叹了。没关系,我们还可以用Schema配置切面

    说白了,其实就是将注解信息移到了Schema的XML配置文件中,形式不同罢了。


    简单实例:

    xml配置文件

    <aop:config proxy-target-class="true">
    		//增强方法所在的bean
    		<aop:aspect ref="adviceMethods">
    			//前置增强
    			<aop:before method="preGreeting"
    				//切点表达式,与@AspectJ的语法相同
    				pointcut="target(com.baobaotao.NaiveWaiter) and args(name)"
    				arg-names="name" />
    			//后置增强
    			<aop:after-returning method="afterReturning"
    				pointcut="target(com.baobaotao.SmartSeller)" returning="retVal" />
    		</aop:aspect>
    	</aop:config>
    	<bean id="adviceMethods" class="com.baobaotao.schema.AdviceMethods" />
    	<bean id="naiveWaiter" class="com.baobaotao.NaiveWaiter" />
    	<bean id="naughtyWaiter" class="com.baobaotao.NaughtyWaiter" />
    	<bean id="seller" class="com.baobaotao.SmartSeller" />

    其中

    1、 <aop:aspect>元素定义切面,内部可以定义多个增强

    2、 <aop:config>拥有一个proxy-target-class属性,true时表示声明的切面采用CGLib动态代理技术;反之表示使用JDK动态代理技术


    增强类:AdviceMethods

    public class AdviceMethods {
    	public void preGreeting(String name) {
    		System.out.println("--how are you!--");
    		System.out.println(name);
    	}
    
        //后置增强对应方法
    	public void afterReturning(int retVal){
    	   System.out.println("----afterReturning()----");
    	   System.out.println("returnValue:"+retVal);
    	   System.out.println("----afterReturning()----");
    	}
    
    }


  • 相关阅读:
    js正则表达式中的问号使用技巧总结
    380. Insert Delete GetRandom O(1)
    34. Find First and Last Position of Element in Sorted Array
    162. Find Peak Element
    220. Contains Duplicate III
    269. Alien Dictionary
    18. 4Sum
    15. 3Sum
    224. Basic Calculator
    227. Basic Calculator II
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3243907.html
Copyright © 2011-2022 走看看