1、AOP 中的概念:
Aspect(切面):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面横切性关注点的抽象.
joinpoint(连接点):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器)
Pointcut(切入点):所谓切入点是指我们要对那些joinpoint进行拦截的定义.
Advice(通知):所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知
Target(目标对象):代理的目标对象
Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入.
Introduction(引入):在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.
2、创建工程
(1) 导入AOP编程的相关 jar 包,如下图所示:
![QQ截图20140226123151 QQ截图20140226123151]()
(2) 要进行AOP编程,首先我们要在spring的配置文件中引入aop命名空间:
xmlns:aop="http://www.springframework.org/schema/aop" 和
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
具体如下:
![]()
<?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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
</beans>
(3) Spring提供了两种切面声明方式,实际工作中我们可以选用其中一种:
<1>基于XML配置方式声明切面。
<2>基于注解方式声明切面。
(4) 基于注解方式声明切面
首先启动对@AspectJ注解的支持,在配置文件中加上 <aop:aspectj-autoproxy/>
具体如下:
![]()
<?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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<aop:aspectj-autoproxy/>
</beans>
(5) 创建包类
<1> 接口
![]()
package org.learn.spring.service;
public interface personService {
public void save(String name);
public void update(String name, Integer id);
public String getPersonServiceName(Integer id);
}
<2> 实现接口类
![]()
package org.learn.spring.service.impl;
import org.learn.spring.service.personService;
public class personServiceImpl implements personService {
@Override
public void save(String name) {
System.out.println("save()方法");
}
@Override
public void update(String name, Integer id) {
System.out.println("update()方法");
}
@Override
public String getPersonServiceName(Integer id) {
System.out.print("getPersonServiceName()方法");
return "xxx";
}
}
<3> 切面类
![]()
package org.learn.spring.service;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
//声明切面
public class MyInterceptor {
//定义要拦截的方法,拦截 personServiceImpl 类下所有方法的执行
/**
* 第一个 * 表示 方法的返回值类型,* 表示任意类型
* org.learn.spring.service.impl.personServiceImpl 表示包下的类, 也可以写成 org.learn.spring.service 这样表示该包下所有的类,以及子包中的类
* 第二个 * 表示方法名称,这里表示是任意的方法,后接括号中的两点是表示参数是任意的,不管参数的个数和参数类型
*/
@Pointcut("execution(* org.learn.spring.service.impl.personServiceImpl.*(..))")
private void anyMethod() {}//声明一个切入点
@Before("anyMethod()")//定义前置通知
public void doAccessCheck() {
System.out.println("前置通知");
}
}
<4> 测试类
![]()
package org.learn.spring.test;
import org.junit.Test;
import org.learn.spring.service.personService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class personTest {
@Test
public void test() {
//实例化spring容器
ApplicationContext cxt = new ClassPathXmlApplicationContext("learn1.xml");
personService service = (personService)cxt.getBean("personService");
service.save("xxx");
}
}
<5> XML 文件
<?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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!-- 基于注解方式声明切面, 首先启动对@AspectJ注解的支持 -->
<aop:aspectj-autoproxy/>
<bean id="personService" class="org.learn.spring.service.impl.PersonServiceImpl"></bean>
<bean class="com.learn.spring.service.MyInterceptor"></bean>
</beans>
(6) 测试,控制台打印出:
![QQ截图20140226125051 QQ截图20140226125051]()