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...











原文地址:https://www.cnblogs.com/wuyida/p/6300347.html