Spring AOP基础实践

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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     @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,对字节码进行动态增强,进行代理。

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

以上是关于Spring AOP基础实践的主要内容,如果未能解决你的问题,请参考以下文章

Spring中关于AOP的实践之Scheme方式实现通知

Spring入门之AOP实践:@Aspect + @Pointcut + @Before / @Around / @After

Spring Aop基础总结

Spring基础之AOP

Spring基础之AOP

Spring基础系列Spring AOP基础