首页 > 代码库 > Spring AOP基础实践

Spring AOP基础实践

一、代码实践

先上代码,Spring AOP的demo,见下面的小例子。

 1 package demo.spring; 2  3 import org.aspectj.lang.annotation.After; 4 import org.aspectj.lang.annotation.Aspect; 5 import org.aspectj.lang.annotation.Before; 6 import org.aspectj.lang.annotation.Pointcut; 7 import org.junit.Test; 8 import org.junit.runner.RunWith; 9 import org.springframework.beans.factory.annotation.Autowired;10 import org.springframework.stereotype.Component;11 import org.springframework.test.context.ContextConfiguration;12 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;13 14 @RunWith(SpringJUnit4ClassRunner.class)15 @ContextConfiguration("classpath:spring-config.xml")16 public class AopDemo {17     @Autowired18     private Target target;19 20     @Test21     public void testSayHello() {22         target.doSomething("hello world");23     }24 }25 26 @Component27 class Target {28     public void doSomething(String params) {29         System.out.println(params);30     }31 }32 33 @Aspect34 @Component35 class Interceptor {36 37     @Pointcut("execution(* demo.spring.Target.doSomething(String)) && args(params)")38     public void doSomething(String params) {}39 40     @Before("doSomething(params)")41     public void before(String params) {42         System.out.println("before params: " + params);43     }44 45     @After("doSomething(params)")46     public void after(String params) {47         System.out.println("after:" + params);48     }49 }

spring-config.xml文件配置如下:

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4        xmlns:context="http://www.springframework.org/schema/context" 5        xmlns:aop="http://www.springframework.org/schema/aop" 6        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> 7 8     <context:component-scan base-package="demo.spring"/> 9     <aop:aspectj-autoproxy />10 11 </beans>

值得说明的点:

* context:component-scan,使用@Autowired自动注入、@Component自动发布bean,两个注解需要配置这个元素,否则无法使用注解;

* aop:aspectj-autoproxy,使用@AspectJ及其它AOP注解需要配置,否则无法使用注解;@AspectJ注解,将@Component自动发布出来的"interceptor" bean转换为一个aspectj切面,而@Pointcut、@Before、@After、@Around等注解,功能与在xml文件中配置是一样的;@Pointcut注解下面的方法内容无意义,只是要求一个相应方法提供注解依附。

* 注解只能在使用能获得源码的场景,如果不能获取源码,则只能通过xml配置的形式,将指定的对象配置成拦截器,对指定的目标进行拦截;因此,通过xml文件配置,而不是注解,是更加通用的方式。

* 除基础的springframework框架的jar包外,还需要依赖cglib、aspectj的jar包,maven配置: 

 1         <dependency> 2             <groupId>cglib</groupId> 3             <artifactId>cglib</artifactId> 4             <version>2.2</version> 5         </dependency> 6         <dependency> 7             <groupId>org.aspectj</groupId> 8             <artifactId>aspectjweaver</artifactId> 9             <version>1.6.11</version>10         </dependency>

 

二、实现原理

Spring框架中的AOP拦截技术,是POJO的方法层面的拦截。关于低层实现原理,其实是动态代理技术。对于面向接口的方法拦截,依赖于jdk的动态代理技术,即java.lang.reflect.Proxy#newProxyInstance,将对被代理的目标对象的调用,委托到代理对象,触发拦截通知;而当被代理的是类对象,不是接口时,使用的是cglib,对字节码进行动态增强,进行代理。

//更多框架底层源码与实现细节,待续。。

Spring AOP基础实践