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()----");
    	}
    
    }


  • 相关阅读:
    方式方法和思维技巧集合
    【NOIP/CSP2019】D2T1 Emiya 家今天的饭
    【NOIP/CSP2019】D1T2 括号树
    【网络流24】餐巾
    【NOIP2016】愤怒的小鸟
    结论和典例集合
    2020牛客寒假集训营第一场题解
    新生训练赛001题解
    The 2014 ACM-ICPC Asia Regional Contest Xi'an Site题解
    SDNU ACM-ICPC 2019 Competition For the End of Term(12-15)山师停训赛题解
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3243907.html
Copyright © 2011-2022 走看看