Spring AOP之动态代理
软件151 李飞瑶
一、Spring 动态代理中的基本概念
1、关注点(concern)
一个关注点可以是一个特定的问题,概念、或者应用程序的兴趣点。总而言之,应用程序必须达到一个目标
安全验证、日志记录、事务管理都是一个关注点
在oo应用程序中,关注点可能已经被代码模块化了还可能散落在整个对象模型中
2、横切关注点(crosscutting concern)
如何一个关注点的实现代码散落在多个类中或方法中
3、方面(aspect)
一个方面是对一个横切关注点模块化,它将那些原本散落在各处的,
用于实现这个关注点的代码规整在一处
4、建议(advice)通知
advice是point cut执行代码,是方面执行的具体实现
5、切入点(pointcut)
用于指定某个建议用到何处
6、织入(weaving)
将aspect(方面)运用到目标对象的过程
7、连接点(join point)
程序执行过程中的一个点
通知类型:
try{
//前置通知
//环绕通知
//调用目标对象方法
//环绕通知
//后置通知
}catch(){
//异常通知
}finally{
//终止通知
}
流程图
二.动态代理实例
项目结构图:
IUserServ接口代码与UserServImpl实现类代码和上述代码相同
LogHandler类代码
- public class LogHandler implements InvocationHandler {
- //目标对象
- private Object targetObject;
- /**
- * 创建动态代理类
- * @return object(代理类)
- */
- public Object createProxy(Object targetObject){
- this.targetObject = targetObject;
- return Proxy.newProxyInstance(
- targetObject.getClass().getClassLoader(),
- targetObject.getClass().getInterfaces(), this);
- }
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- Object obj = null;
- try {
- beforeLog();
- //obj: 目标对象--->代理对象的返回值--->返回给调用者的信息
- //this.invoke("目标对象","代理对象给目标对象传递参数");
- //调用目标对象中方法
- obj = method.invoke(targetObject, args);
- afterLog();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return obj;
- }
- //日志管理方法
- private void beforeLog(){
- System.out.println("开始执行");
- }
- private void afterLog(){
- System.out.println("执行完毕");
- }
- }
ActionTest测试类代码:
- public class ActionTest {
- public static void main(String[] args) {
- //创建代理对象iuserServ
- LogHandler handler = new LogHandler();
- IUserServ iuserServ = (IUserServ)handler.createProxy(new UserServImpl());
- iuserServ.deleteUserById(new User());
- }
- }
运行结果:
开始执行
******执行删除方法******
执行完毕
三.Spring AOP使用(2.x版本之前)
项目结构图:
IUserServ接口代码与UserServImpl实现类代码和上述代码相同
配置步骤:
1、配置目标对象(applicationContext.xml)
- <bean id="userServTarget" class="com.tarena.biz.impl.UserServImpl"/>
2、配置通知
(a)前置通知(BeforeLogAdvice)
- public class BeforeLogAdvice implements MethodBeforeAdvice {
- /**
- * Method method:调用目标对象的方法
- * Object[] args:发送给目标对象的参数列表
- * Object target:目标对象
- */
- public void before(Method method, Object[] args, Object target)
- throws Throwable {
- beforeLog();
- }
- private void beforeLog(){
- System.out.println("开始执行");
- }
- }
(b)后置通知(AfterLogAdvice)
- public class AfterLogAdvice implements AfterReturningAdvice {
- /**
- * Object returnValue:目标对象返回值
- * Method method:目标对象方法名
- * Object[] args:目标对象参数列表
- * Object target:目标对象
- */
- public void afterReturning(Object returnValue, Method method,
- Object[] args, Object target) throws Throwable {
- afterLog();
- }
- private void afterLog(){
- System.out.println("执行完毕");
- }
- }
(c)在spring容器中,让容器管理通知(applicationContext.xml)
- <!-- 定义通知 -->
- <!-- 前置通知 -->
- <bean id="beforeLogAdvice" class="com.tarena.advice.BeforeLogAdvice"/>
- <!-- 后置通知 -->
- <bean id="afterLogAdvice" class="com.tarena.advice.AfterLogAdvice"/>
3、配置代理对象(applicationContext.xml)
- <!-- 代理类作用: 生成代理类,织入通知 -->
- <bean id="userServProxy"
- class="org.springframework.aop.framework.ProxyFactoryBean">
- <property name="interfaces">
- <!-- 可以添加多个接口 -->
- <list>
- <value>com.tarena.biz.IUserServ</value>
- </list>
- </property>
- <!-- 引入通知 -->
- <property name="interceptorNames">
- <list>
- <value>beforeLogAdvice</value>
- <value>afterLogAdvice</value>
- </list>
- </property>
- <!-- 目标对象 -->
- <property name="target" ref="userServTarget"/>
- </bean>
4.访问()
Spring容器:通过代理对象调用-->织入通知--->目标对象
程序员:访问代理对象
测试类(ActionTest):
- public class ActionTest {
- public static void main(String[] args) {
- ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
- IUserServ iuserServ = (IUserServ)ac.getBean("userServProxy");
- iuserServ.deleteUserById(new User());
- iuserServ.findAllUser();
- }
- }
运行结果:
开始执行
******执行删除方法******
执行完毕
开始执行
*******执行查询方法*******
执行完毕
四.Spring AOP使用(2.x版本之后)这种方式需要额外添加两个jar包,
存放位置在spring-framework-2.5.6.SEC01\lib\aspectj文件夹下。
项目结构图
IUserServ接口代码与UserServImpl实现类代码和上述代码相同
LogAdvice中
- public class LogAdvice {
- public void beforeLog(){
- System.out.println("开始执行");
- }
- public void afterLog(){
- System.out.println("执行完毕");
- }
- }
applicationContext.xml中
- <!-- spring2.x后 -->
- <!-- 目标对象 -->
- <bean id="userServImpl" class="com.tarena.biz.impl.UserServImpl"/>
- <!-- 通知 -->
- <bean id="logAdvice" class="com.tarena.advice.LogAdvice"/>
- <aop:config>
- <aop:aspect id="logAspect" ref="logAdvice">
- <!-- 切入点 -->
- <aop:pointcut id="beforePointCut"
- expression="execution(* saveUser*(..))"/>
- <aop:pointcut id="afterPointCut"
- expression="execution(* saveUser*(..))"/>
- <!-- 织入(通知作用于切入点) -->
- <aop:before method="beforeLog" pointcut-ref="beforePointCut"/>
- <aop:after method="afterLog" pointcut-ref="afterPointCut"/>
- </aop:aspect>
- </aop:config>
测试类:
- public class ActionTest {
- public static void main(String[] args) {
- ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
- IUserServ iuserServ = (IUserServ)ac.getBean("userServImpl");
- iuserServ.deleteUserById(new User());
- iuserServ.findAllUser();
- iuserServ.saveUser(new User());
- }
- }
运行结果
******执行删除方法******
*******执行查询方法*******
开始执行
*******执行添加方法********
执行完毕
注:如果要在业务层所有的方法前后添加日志文件,则需要更改为以下配置
- <aop:pointcut id="beforePointCut"
- expression="execution(* com.tarena.biz.*.*(..))"/>
- <aop:pointcut id="afterPointCut"
- expression="execution(* com.tarena.biz.*.*(..))"/>
运行结果:
开始执行
******执行删除方法******
执行完毕
开始执行
*******执行查询方法*******
执行完毕
开始执行
*******执行添加方法********
执行完毕
Spring AOP之动态代理的更多相关文章
- Spring AOP 和 动态代理技术
AOP 是什么东西 首先来说 AOP 并不是 Spring 框架的核心技术之一,AOP 全称 Aspect Orient Programming,即面向切面的编程.其要解决的问题就是在不改变源代码的情 ...
- Spring AOP --JDK动态代理方式
我们知道Spring是通过JDK或者CGLib实现动态代理的,今天我们讨论一下JDK实现动态代理的原理. 一.简述 Spring在解析Bean的定义之后会将Bean的定义生成一个BeanDefinit ...
- Spring AOP JDK动态代理与CGLib动态代理区别
静态代理与动态代理 静态代理 代理模式 (1)代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. (2)静态代理由 业务实现类.业务代理类 两部分 ...
- Spring AOP 前奏--动态代理
- 深入理解Spring AOP之二代理对象生成
深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 ...
- AOP jdk动态代理
一: jdk动态代理是Spring AOP默认的代理方法.要求 被代理类要实现接口,只有接口里的方法才能被代理,主要步骤是先创建接口,接口里创建要被代理的方法,然后定义一个实现类实现该接口,接着将被代 ...
- 浅谈Spring中JDK动态代理与CGLIB动态代理
前言Spring是Java程序员基本不可能绕开的一个框架,它的核心思想是IOC(控制反转)和AOP(面向切面编程).在Spring中这两个核心思想都是基于设计模式实现的,IOC思想的实现基于工厂模式, ...
- AOP与动态代理有什么联系
曾遇到“AOP与动态代理有什么联系”的问题,现把个人观点整理如下: 我觉得,动态代理是AOP的主要实现手段之一,AOP是动态代理的一种应用深化 AOP是一种思想,或者是方法论,类似OOP,是OOP的有 ...
- 【Java EE 学习 51】【Spring学习第三天】【cglib动态代理】【AOP和动态代理】【切入点表达式】
一.cglib动态代理 1.简介 (1)CGlib是一个强大的,高性能,高质量的Code生成类库.它可以在运行期扩展Java类与实现Java接口. (2) 用CGlib生成代理类是目标类的子类. (3 ...
随机推荐
- BUPT2017 springtraining(16) #1 ——近期codeforces简单题目回顾
这里是contest 8道题全部来源于 cf 的两场contest (出题人可真懒啊 Codeforces Round #411 (Div. 2)的ABCDE Codeforces Round #40 ...
- Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method fail
SpringBoot 单元测试报错 @RunWith(SpringRunner.class) @SpringBootTest public class ProductCategoryRepositor ...
- Excel 2010/2013/2016在鼠标右键新建xls或xlsx文件后,打开报错“无法打开文件”“文件格式或文件扩展名无效”
近段时间,陆续有两个同事先后出现同样的问题(在Excel多个版本都可能出现),问题描述: 当用鼠标右键在任意文件夹或电脑桌面“新建”→“ Microsoft Excel 工作表”,再用鼠标双击打开这个 ...
- HyperLedger项目以及社区
本文不涉及任何技术开发的内容,仅供你跟同学.同事吹牛B之用.就像很多牛人总爱讲历史典故一样. 一.诞生与现状 HyperLedger 诞生于2015年12月17日,HyperLedger 追寻Apac ...
- VB.NET机房收费 & 抽象工厂模式
学习设计模式的时候,提到了一个专门訪问数据库的模式-抽象工厂模式,记得当时举样例理解的时候并未设计到数据库,仅仅是大概了了解了一下,如今对于机房收费系统涉及到了数据库的管理,借此机会好好学习一下.用常 ...
- 2014年辛星jquery解读第三节 Ajax
***************Ajax********************* 1.Ajax是Asynchronous Javascript And XML的简写,它指的是异步Javascript ...
- linux c编程訪问数据库
源代码例如以下: #include <stdio.h> #include <stdlib.h> #include <mysql/mysql.h> int main( ...
- poj 1080 Human Gene Functions (最长公共子序列变形)
题意:有两个代表基因序列的字符串s1和s2,在两个基因序列中通过添加"-"来使得两个序列等长:其中每对基因匹配时会形成题中图片所示匹配值,求所能得到的总的最大匹配值. 题解:这题运 ...
- MySql存储过程与函数
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:存储过程和函数是在数据库中定义一些SQL语句的集合,然后直接调用这些存储过程和函数来运行 ...
- hdu 4932 Miaomiao's Geometry(暴力枚举)
pid=4932">Miaomiao's Geometry ...