尚学堂Spring视频教程(五):Spring AOP
在第一节中,我们自己模拟了一个Spring,实现一个保存用户的操作,假如现在有一个需求,在保存的时候记录日志,该怎么做呢?
暂且将记录日志操作就简单的变为在保存用户前输出一句话“save start...”,不建议直接在UserDAOImpl的save方法里写代码,因为我们有时候可能得不到源码,这个时候可以添加一个UserDAOImpl2继承UserDAOImpl,然后调用父类的save方法
package com.bjsxt.dao.impl; import com.bjsxt.model.User; public class UserDAOImpl2 extends UserDAOImpl {
@Override
public void save(User user) { System.out.println("save start...");
super.save(user); }
}
UserDAOImpl2
注:配置文件被注入到UserService的bean的class要改为UserDAOImpl2,下面也一样
看似实现了效果,但是这样很不灵活,因为只能继承一个类,而且父类发生变化,子类也必须跟着做出改变,我们可以再添加一个类继承UserDAOImpl,但是采用组合的方法
package com.bjsxt.dao.impl; import com.bjsxt.aop.LogInterceptor;
import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User; public class UserDAOImpl3 implements UserDAO { private UserDAO userDAO = new UserDAOImpl(); public void save(User user) {
System.out.println("save start...");
/*new LogInterceptor().beforeMethod(null);*/
userDAO.save(user); } /*public void delete() {
// TODO Auto-generated method stub }*/
}
UserDAOImpl3
问题又来了,如果系统有500个需要被注入的bean,每个bean都有一些操作需要被记录日志,难道要组合500个bean来实现这个功能吗?
实际上可以给UserDAOImpl产生了一个代理,我们知道在代理模式中代理类除了可以调用目标对象的方法,也可以在方法前后加入自己的逻辑,在这里就是日志记录
在JAVA基础知识:代理这篇文章中,介绍了Proxy类的静态方法newProxyInstance,这个方法需要三个参数,第一个是类装载器,第二个是目标对象的接口,第三个是InvocationHandler,这个最重要,定义了一个invoke方法,方法中可以调用目标对象的方法,也可以添加日志记录的逻辑代码
新建一个包com.bjsxt.aop,添加类LogInterceptor继承InvocationHandler
package com.bjsxt.dao.impl; import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User; public class UserDAOImpl implements UserDAO { public void save(User user) { //Hibernate
//JDBC
//XML
//NetWork
System.out.println("user saved!");
} public void delete() {
System.out.println("user deteleted"); } }
UserDAOImpl
package com.bjsxt.aop; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class LogInterceptor implements InvocationHandler {
private Object target; public Object getTarget() {
return target;
} public void setTarget(Object target) {
this.target = target;
} public void beforeMethod(Method m) { System.out.println(m.getName() + " start");
} public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
beforeMethod(m);
m.invoke(target, args);
return null;
}
}
InvocationHandler接口的实现类
@Test
public void testProxy() {
UserDAO userDAO = new UserDAOImpl();
LogInterceptor li = new LogInterceptor();
li.setTarget(userDAO);
UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), li);
System.out.println(userDAOProxy.getClass());
userDAOProxy.delete();
userDAOProxy.save(new User()); }
单元测试
我们只需要写一次日志记录的代码,就完成delete和add用户的日志记录工作
项目结构如下:
尚学堂Spring视频教程(五):Spring AOP的更多相关文章
- spring boot(五)Spring data jpa介绍
在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spr ...
- 框架应用:Spring framework (五) - Spring MVC技术
软件开发中的MVC设计模式 软件开发的目标是减小耦合,让模块之前关系清晰. MVC模式在软件开发中经常和ORM模式一起应用,主要作用是将(数据抽象,数据实体传输和前台数据展示)分层,这样前台,后台,数 ...
- spring入门(五) spring mvc+hibernate
核心是让SessionFactory由Spring管理 1.引入依赖 <!-- https://mvnrepository.com/artifact/org.springframework/sp ...
- Spring详解(五)------AOP
这章我们接着讲 Spring 的核心概念---AOP,这也是 Spring 框架中最为核心的一个概念. PS:本篇博客源码下载链接:http://pan.baidu.com/s/1skZjg7r 密码 ...
- spring(五):AOP
AOP(Aspect Oriented Programming) 面向切面编程,是一种编程范式,提供从另一个角度来考虑程序结构从而完善面向对象编程(OOP). 在进行OOP开发时,都是基于对组件(比如 ...
- 十五 Spring的AOP的注解的通知类型,切入点的注解
Spring的注解的AOP的通知类型 @Before:前置通知 @AfterReturning:后置通知 @Around:环绕通知 @AfterThrowing:异常抛出通知 @After:最终通知 ...
- 【Spring Framework】Spring入门教程(五)AOP思想和动态代理
本文主要讲解内容如下: Spring的核心之一 - AOP思想 (1) 代理模式- 动态代理 ① JDK的动态代理 (Java官方) ② CGLIB 第三方代理 AOP概述 什么是AOP(面向切面编程 ...
- [JAVA教程] 2016年最新spring4框架搭建视频教程 【尚学堂】
Spring4框架 主讲:邹波 类型:SSH 适合对象:学习完javase.数据库技术.jdbc者 Spring4.0作为一个广泛使用的开源框架,它由Rod Johnson创建.它是为了解决企业应用开 ...
- Spring学习笔记4——AOP
AOP 即 Aspect Oriented Program 面向切面编程 首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能. 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务 ...
- Spring基础篇——Spring的AOP切面编程
一 基本理解 AOP,面向切面编程,作为Spring的核心思想之一,度娘上有太多的教程啊.解释啊,但博主还是要自己按照自己的思路和理解再来阐释一下.原因很简单,别人的思想终究是别人的,自己的理解才是 ...
随机推荐
- Linux crontab命令格式与详情例子
基本格式 : * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示 第2列表示小时1-23(0表示0点) 第3列表示日期1-31 第4列表示 ...
- JS的字符串处理
1.字符串包含判断 var a = "qwer"; var b = "q"; if (a.contains(b)) { alert("1") ...
- Kali Linux additional tools setup
The steps are pretty straight forward. The only tool that might cause some confusion is SMBexec. Thi ...
- FreeBSD 无线配置
无线配置在 handbook 中早已有了,但 handbook 中采用写入配置文件的办法,缺乏灵活性,补充下 on the fly 的方法 假设网卡接口为 ath0 ifconfig wlan0 cr ...
- Baidu set to lose leading role in digital advertising _china daily
advertising: n,广告 Online search giant Baidu Inc is set to loset its top spot in the nation's booming ...
- js 防止页面后退的方法
//防止页面后退 history.pushState(null, null, document.URL); window.addEventListener('popstate', function ( ...
- HashMap 与 HashTable的区别
1.HashTable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就像Vector和ArrayList一样.可以用synchronized实现HashMap ...
- [API]使用Blueprint来高雅的编写接口文档 前后端api文档,移动端api文档
网址:http://apiary.io/ 介绍:一款非常强大的前后端交互api设计编辑工具(编辑器采用Markdown类似的描述标记,非常高效),高颜值的api文档,还能生成多种语言的测试代码. 中文 ...
- 调试新技能get - powershell
1. win+r -> powershell_ise 2. debug-process 3. type processname....WITHOUT ".exe"
- apache 使用 .htaccess 导致500错误
今天在win主机上配置了一个apache+mysql+php 的环境,一切看似正常了.结果将程序转移过来,打开网站的时候,出现了500错误.于是乎查原因: 首先,怀疑的是连接mysql出错了,找出配置 ...