• Spring AOP (一)


    一、AOP 是什么?

           AOP 是Aspect Oriented Programaing 的简称,意思是面向切面编程,AOP的应用场合是受限的,一般只适合于那些具有横切逻辑的应用场合:如性能检测、访问控制、事务管理以及日志记录。


    二、AOP 术语

              1、连接点: 程序执行的某个特定位置,如类开始初始化前,类初始化后、类某个方法调用前、调用后、方法抛出异常后;一个类或一断程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就称为连接点。

               2、切点

              3、增强(Advice)

              4、目标对象

              5、引介(Introduction)

              6、织入(Weaving)

              7、代理(Proxy)

              8、切面(Aspect)


    三、基于@AspectJ的AOP

     一个简单的例子

    定义一个接口和实现类,作为增强的目标对象.

    package com.baobaotao;
    
    public interface Waiter {
    	public void greetTo(String clientName);	
    	public void serveTo(String clientName);
    }
    

    package com.baobaotao;
    
    public class NaiveWaiter implements Waiter {
    
    	public void greetTo(String clientName) {
    		System.out.println("NaiveWaiter:greet to "+clientName+"...");
    	}
    
    	public void serveTo(String clientName) {
    		System.out.println("NaiveWaiter:serving "+clientName+"...");
    
    	}
    	public void smile(String clientName,int times){
    		System.out.println("NaiveWaiter:smile to  "+clientName+ times+"times...");
    	}	
    
    }
    
    然后,我们通过@Aspect注解定义一个切面,里面包含切点、增强类型和增强的横切逻辑.

    package com.baobaotao.aspectj;
    
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    
    @Aspect //(1)通过该注解将PreGreetingAspect标识为一个切面
    public class PreGreetingAspect {
    	@Before("execution(* greetTo(..))")//(2)定义切点和增强类型(前置增强before)
    	public void beforeGreeting(){//(3)增强的横切逻辑
    		System.out.println("How are you!");
    	}
    }

    我们通过org.springframework.aop.aspectj.annotation.AspectJProxyFactory 为NativeWaiter生成织入PreGreetingAspect切面的代理,如下:

    package com.baobaotao.aspectj;
    
    import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
    
    import com.baobaotao.NaiveWaiter;
    import com.baobaotao.Waiter;
    
    public class AspectJProxyTest {
    	
    	public static void main(String[] args) {
    		Waiter target=new NaiveWaiter();
    		AspectJProxyFactory factory=new AspectJProxyFactory();
    		//设置目标对象
    		factory.setTarget(target);
    		//添加切面类
    		factory.addAspect(PreGreetingAspect.class);
    		//生成织入切面的代理对象
    		Waiter proxy=factory.getProxy();
    		proxy.greetTo("John");
    		proxy.serveTo("John");
    	}
    }
    
    运行后输出:

    log4j:WARN No appenders could be found for logger (org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory).
    log4j:WARN Please initialize the log4j system properly.
    How are you!
    NaiveWaiter:greet to John...
    NaiveWaiter:serving John...
    

    至此代理对象的greeTo方法已经织入了切面类所定义的增强逻辑了.


    四、如何通过配置使用@AspectJ切面

    前面是使用编程方式织入切面 ,一般情况下我们是通过Spring的配置完成切面的织入的工作. 使用AOP命名空间,自动将切面织入到目标Bean中.

    <?xml version="1.0" encoding="UTF-8"?>
    
    <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-3.0.xsd
                                 http://www.springframework.org/schema/aop
                                  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
            <!-- 基于@Aspect切面的驱动器 --> 
            <aop:aspectj-autoproxy/>
             <!-- 目标Bean -->   
             <bean id="waiter" class="com.baobaotao.NaiveWaiter"/>
             <!-- 使用了@Aspect注解的切面类 -->
             <bean class="com.baobaotao.aspectj.PreGreetingAspect" />   
           <!-- 自动代理创建器,自动将@Aspect注解切面类织入到目标Bean中 -->  
              <!-- 不使用aop命名空间 -->
           <!--  <bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/>              
           -->
    </beans>

    注解在配置文件中引入aop命名空间,然后通过aop命名空间的<aop:aspectj-autoproxy/> 自动为Spring容器中那些匹配@Apsect切面的Bean创建代理,完成切面织入。当然,Spring在内部依旧采用AnnotationAwareAspectJAutoProxyCreator  

                进行自动代理的创建工作,但具体的实现细节已经被<aop:aspectj-autoproxy/> 隐藏起来了.

                <aop:aspectj-autoproxy/>有一个proxy-target-class属性,默认为false,表示使用JDK动态代理织入增强,当配置为<aop:aspectj-autoproxy   proxy-target-class ="true">时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类设有声明接口,则Spring将自动使用CGLib动态代理。

           

              下面我们对上面的配置进行测试:

         

    package com.baobaotao.aspectj;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.baobaotao.Waiter;
    
    public class TestPreGreetingAspect {
    	
    	public static void main(String[] args) {
    		ApplicationContext ctx=new ClassPathXmlApplicationContext("com/baobaotao/aspectj/aop.xml");
    		Waiter waiter=(Waiter) ctx.getBean("waiter");
    		waiter.greetTo("Tom");
    		waiter.serveTo("Tom");
    	}
    }
    

    输出:

    log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
    log4j:WARN Please initialize the log4j system properly.
    How are you!
    NaiveWaiter:greet to Tom...
    NaiveWaiter:serving Tom...
    











  • 相关阅读:
    eclipse/intellij idea 查看java源码和注释
    理解线程池,看这篇足够了-转
    乐观锁的幂等性方案
    springboot2.0以后的junit
    详解 Java 中的三种代理模式
    MYSQL慢查询配置
    MySQL 数据库性能优化之SQL优化【转】
    SQL中EXPLAIN命令详解---(转)
    spring的面试
    sql joins 7
  • 原文地址:https://www.cnblogs.com/wuyida/p/6300347.html
Copyright © 2020-2023  润新知