IT虾米网

Spring AOP介绍1

zdz8207 2022年08月05日 编程语言 45 0

一、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://blog.csdn.net/yulei_qq/article/details/44513611
评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler