AOP(Aspect Orient Programming),也就是面向切面编程。可以这样理解,面向对象编程(OOP)是从静态角度考虑程序结构,面向切面编程(AOP)是从动态角度考虑程序运行过程。
AOP原理图
下面是一个spring aop的零配置的例子(用maven构建)。
配置文件
<?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:context="http://www.springframework.org/schema/context"
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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!-- 指定自动搜索 Bean 组件、自动搜索方面类 -->
<context:component-scan base-package="com.bobohe">
<context:include-filter type="annotation"
expression="org.aspectj.lang.annotation.Aspect" />
</context:component-scan>
<!-- 启动 @AspectJ 支持 -->
<aop:aspectj-autoproxy />
</beans>
目标对象类
package com.bobohe.test01;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* Hello world!
*
*/
@Component("app")
public class App implements AppInterface
{
public void testAspectJ(String param){
System.out.println("do test AspectJ:" + param);
}
}
目标对象接口
package com.bobohe.test01;
public interface AppInterface {
public void testAspectJ(String param);
}
junit测试类
package com.bobohe.test01;
import com.bobohe.test01.App;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Unit test for simple App.
*/
public class AppTest extends TestCase {
public void testApp() {
BeanFactory bf = new ClassPathXmlApplicationContext("ApplicationContext.xml");
AppInterface at = (AppInterface) bf.getBean("app");
at.testAspectJ("real params");
System.out.println(at.getClass());
assertTrue(true);
}
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bobohe</groupId>
<artifactId>springtest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springtest</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.4.RELEASE</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.3</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.3</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</project>
输出结果
执行目标方法之前,模拟开始事务 ...
do test AspectJ:被改变的参数
执行目标方法之后,模拟结束事务 ...
class sun.proxy.$Proxy8
从输出结果看,在这个例子中spring用的jdk的动态代理来创建aop代理的。但是当我们的被代理的对象类没有继承接口是,spring会使用cglib来生成aop代理。这一层是spring帮我们处理的。spring会根据实际情况自动切换。