标签:
一、代码实践
先上代码,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 @Autowired 18 private Target target; 19 20 @Test 21 public void testSayHello() { 22 target.doSomething("hello world"); 23 } 24 } 25 26 @Component 27 class Target { 28 public void doSomething(String params) { 29 System.out.println(params); 30 } 31 } 32 33 @Aspect 34 @Component 35 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,对字节码进行动态增强,进行代理。
//更多框架底层源码与实现细节,待续。。
标签:
原文地址:http://www.cnblogs.com/jacksonshi/p/5863313.html