Spring框架学习07——基于传统代理类的AOP实现
在Spring中默认使用JDK动态代理实现AOP编程,使用org.springframework.aop.framework.ProxyFactoryBean创建代理是Spring AOP 实现的最基本方式。
1、通知类型
根据Spring中通知在目标类方法中的连接点位置,通知可以分为6种类型:
(1)环绕通知
环绕通知(org.aopalliance.intercept.MethodInterceptor)是在目标方法执行前和执行后实施增强,可应用于日志记录、事务处理等功能。
(2)前置通知
前置通知(org.springframework.aop.MethodBeforeAdvice)是在目标方法执行前实施增强,可应用于权限管理等功能。
(3)后置返回通知
后置返回通知(org.springframework.aop.AfterReturningAdvice)是在目标方法成功执行后实施增强,可应用于关闭流、删除临时文件等功能。
(4)后置(最终)通知
后置通知(org.springframework.aop.AfterAdvice)是在目标方法执行后实施增强,与后置返回通知不同的是,不管是否发生异常都要执行该类通知,该类通知可应用于释放资源。
(5)异常通知
异常通知(org.springframework.aop.ThrowsAdvice)是在方法抛出异常后实施增强,可应用于处理异常、记录日志等功能。
(6)引入通知
引入通知(org.springframework.aop.IntroductionInterceptor)是在目标类中添加一些新的方法和属性,可应用于修改目标类(增强类)。Spring AOP 只支持方法层面的增强,所以该类型的通知只作为了解即可。
2、切面类型
- Advisor:代表一般切面,Advice本身就是一个切面,对目标类所有方法进行拦截
- PointcutAdvisor:代表具有切点的切面,可以指定拦截目标类哪些方法
- IntroductionAdvisor:代表引介切面,针对引介通知而使用切面
3、ProxyFactoryBean
ProxyFactoryBean是org.springframework.beans.factory.FactoryBean 接口的实现类,FactoryBean负责实例化一个Bean实例,ProxyFactoryBean负责为其他Bean实例创建代理实例。ProxyFactoryBean类的常用属性如下:
- target:代理的目标对象
- proxyInterfaces:代理需要实现的接口列表,如果是多个接口,可以使用以下格式赋值:<list> <value></value> </list>
- InterceptorNames:需要织入目标的Advice
- proxyTargetClass:是否对类代理而不是接口,默认为false,使用JDK动态代理;当为true时,使用CGLIB动态代理
- singleton:返回的代理实例是否为单例,默认为true
- optimize:当设置为true时强制使用CGLIB动态代理
4、Advisor一般切面的实现
在pom.xml中导入AOP联盟和Spring-aop的相关依赖
<!-- AOP联盟依赖 -->
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
创建StuDao接口和StuDaoImpl实现类,示例代码如下:
StuDao接口
public interface StuDao {
public void save();
public void modify();
public void delete();
}
StuDaoImpl实现类
public class StuDaoImpl implements StuDao {
@Override
public void save() {
System.out.println("保存");
}
@Override
public void modify() {
System.out.println("修改");
}
@Override
public void delete() {
System.out.println("删除");
}
}
创建切面类MyBeforeAdvice,仅实现前置通知
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method; public class MyBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("前置增强========");
}
}
在applicationContext.xml中配置切面并指定代理
<!--配置目标类-->
<bean id="stuDao" class="aop.StuDaoImpl"></bean>
<!--配置前置通知类型-->
<bean id="myBeforeAdvice" class="aop.MyBeforeAdvice"></bean>
<!--Spring AOP 生成代理对象-->
<bean id="stuDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--配置目标类-->
<property name="target" ref="stuDao"></property>
<!--代理实现的接口-->
<property name="proxyInterfaces" value="aop.StuDao"></property>
<!--采取拦截的名称-->
<property name="interceptorNames" value="myBeforeAdvice"></property>
</bean>
创建测试类
@Test
public void demo(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
StuDao stuDao = (StuDao) app.getBean("stuDaoProxy");
stuDao.save();
stuDao.modify();
stuDao.delete();
}
运行结果

5、PointcutAdvisor切点切面的实现
使用普通Advice作为切面,将对目标类所有方法进行拦截,不够灵活,在实际开发中常采用带切点的切面。
常用PointcutAdvisor实现类:
- DefaultPointcutAdvisor最常用的切面类型,它可以通过任意Pointcut和Advice组合定义切面;
- JdkRegexpMethodPointcut构造正则表达式切点(推荐)
创建StuDao接口和StuDaoImpl实现类,示例代码如下:
StuDao接口
public interface StuDao {
public void save();
public void modify();
public void delete();
}
StuDaoImpl实现类
public class StuDaoImpl implements StuDao {
@Override
public void save() {
System.out.println("保存");
}
@Override
public void modify() {
System.out.println("修改");
}
@Override
public void delete() {
System.out.println("删除");
}
}
下面创建一个实现环绕通知的切面类
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; public class MyAspect implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation m) throws Throwable {
//前置增强方法
check();
//执行目标方法
Object obj = m.proceed();
//后置增强方法
log();
return obj;
} public void check(){
System.out.println("模拟权限控制");
}
public void log(){
System.out.println("模拟日志记录");
}
}
在applicationContext.xml中配置切面并指定代理
<!--配置目标类-->
<bean id="stuDao" class="aop.StuDaoImpl"></bean>
<!--配置通知-->
<bean id="myAspect" class="aop.MyAspect"></bean>
<!--配置带切入点的切面-->
<bean id="myAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!--pattern中配置正则表达式:.表示任意字符 *表示任意次数-->
<property name="pattern" value=".*"></property>
<property name="advice" ref="myAspect"></property>
</bean>
<!--Spring AOP 生成代理对象-->
<bean id="stuDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--配置目标类-->
<property name="target" ref="stuDao"></property>
<!--代理实现的接口-->
<property name="proxyInterfaces" value="aop.StuDao"></property>
<!--采取拦截的名称-->
<property name="interceptorNames" value="myAdvisor"></property>
</bean>
创建测试类
@Test
public void demo(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
StuDao stuDao = (StuDao) app.getBean("stuDaoProxy");
stuDao.save();
stuDao.modify();
stuDao.delete();
}
运行结果

Spring框架学习07——基于传统代理类的AOP实现的更多相关文章
- Spring框架学习笔记(8)——AspectJ实现AOP
使用代理对象实现AOP虽然可以满足需求,但是较为复杂,而Spring提供一种简单的实现AOP的方法AspectJ 同样的计算器的DEMO 首先配置applicationContext.xml < ...
- Spring框架学习09——基于AspectJ的AOP开发
1.基于注解开发AspectJ (1)AspectJ注解 基于注解开发AspectJ要比基于XML配置开发AspectJ便捷许多,所以在实际开发中推荐使用注解方式.关于注解的相关内容如下: @Aspe ...
- Spring框架学习08——自动代理方式实现AOP
在传统的基于代理类的AOP实现中,每个代理都是通过ProxyFactoryBean织入切面代理,在实际开发中,非常多的Bean每个都配置ProxyFactoryBean开发维护量巨大.解决方案:自动创 ...
- Spring AOP(基于代理类的AOP实现)
#基于代理类的AOP实现:step1: 1 package com.sjl.factorybean; /**切面类*/ import org.aopalliance.intercept.MethodI ...
- Spring框架学习总结(上)
目录 1.Spring的概述 2.Spring的入门(IOC) 3.Spring的工厂类 4.Spring的配置 5.Spring的属性注入 6.Spring的分模块开发的配置 @ 1.Spring的 ...
- Spring框架学习一
Spring框架学习,转自http://blog.csdn.net/lishuangzhe7047/article/details/20740209 Spring框架学习(一) 1.什么是Spring ...
- Spring框架学习1
AnonymouL 兴之所至,心之所安;尽其在我,顺其自然 新随笔 管理 Spring框架学习(一) 阅读目录 一. spring概述 核心容器: Spring 上下文: Spring AOP ...
- Spring框架学习之IOC(二)
Spring框架学习之IOC(二) 接着上一篇的内容,下面开始IOC基于注解装配相关的内容 在 classpath 中扫描组件 <context:component-scan> 特定组件包 ...
- Spring框架学习笔记(1)
Spring 框架学习笔记(1) 一.简介 Rod Johnson(spring之父) Spring是分层的Java SE/EE应用 full-stack(服务端的全栈)轻量级(跟EJB比)开源框架, ...
随机推荐
- Fragment的常用写法
一般通过add.show.hide相结合的方法来控制Fragment的显示和隐藏,这样不会再重写一遍Fragment的生命周期,节省了时间和内存,当然特殊需求除外. package com.examp ...
- SSH开发环境搭建
断断续续学习hibernate也有一段时间了,在这里研究一下SSH开发环境的搭建过程,自己简单的搭建一个SSH的开发环境.采用maven搭建. 0.项目结构: 1.导包:(maven项目) pom.x ...
- Freemarker导出带格式的word的使用
1.新建一个doc文档
- Django 查询集简述
通过模型中的管理器构造一个查询集(QuerySet),来从数据库中获取对象.查询集表示从数据库中取出来的对象的集合.它可以含有零个.一个或者多个过滤器.过滤器基于所给的参数限制查询的结果. 从SQL ...
- libevent 和 libev 提高网络应用性能
构建现代的服务器应用程序需要以某种方法同时接收数百.数千甚至数万个事件,无论它们是内部请求还是网络连接,都要有效地处理它们的操作.有许多解决方 案,但是 libevent 库和 libev 库能够大大 ...
- 017_mac格式化硬盘,mac如何格式化硬盘
想做一个mac和windows都能识别的系统,推荐设置成什么格式 一.在mac下格式化 在Mac 下,打开右下角应用程序-实用工具-磁盘工具,里面选取你的移动硬盘,然后进行格式化,设置成EXFat格式 ...
- java.util.Map
map时key/value形式存储信息的,键可以为对象null public static void main(String[] args) { Map<String, String> m ...
- Android:自定义Dialog
自定义Dialog:显示SeekBar 效果图: 步骤: //SettingActivity.java button4.setOnClickListener(new View.OnClickListe ...
- [转]Apache Commons IO入门教程
Apache Commons IO是Apache基金会创建并维护的Java函数库.它提供了许多类使得开发者的常见任务变得简单,同时减少重复(boiler-plate)代码,这些代码可能遍布于每个独立的 ...
- selenium和pyquery抓取异步加载数据
安装selenium和pyquery 打开命令行输入: pip install selenium pip install pyquery chromedriver的下载地址如下: http://chr ...