Aop_面向切面编程_思想理解资料01
来源:互联网 发布:一叶随风天下知秋 编辑:程序博客网 时间:2024/05/20 10:13
开发人员在编写应用程序时,通常包含两种代码:一种是和业务系统有关系的代码,一种是和业务系统关系不大的代码,例如日志,事务处理,权限处理等等。以前的程序中,这两种代码是写在一起的。这样一来,程序中到处充满着相同或类似的代码,不利于维护。而Aop的目标就是使这两种代码分离解耦,这样程序员就能专心于业务的处理,而且达到维护和重用的目的。
拿日志记录这个例子来看。每个方法都需要进行日志记录,不使用Aop的时候,每个方法中都要包含日志记录的代码,这样就会产生重复,而且日志记录和业务代码紧紧耦合,不利于维护。使用AOP的思想,可以把日志看成是一个切面,所有需要日志记录的方法都要经过这个切面。这样就可以把日志记录的代码封装,当方法经过切面的时候执行,这样就实现了代码重用。
Aop和oop的关系
一个程序分为核心关注点和横切关注点,oop关注核心,aop关注横切。在aop中每个关注点并不知道是否有其他关注点关注它,这是oop和aop的区别。Oop和aop是互补的思想,而不是对立。
Aop和java的代理机制
Aop是一种思想,他和具体的实现技术无关。任何符合aop思想的技术实现都可以看做是Aop的实现。
Jdk 1.3之后java提供动态代理机制。通过java的动态代理可以轻松实现Aop。事实上spring的Aop也是建立在java的动态代理机制之上的。要理解spring,就要先理解java的动态代理机制。
通过日志记录的实例分析AOP思想
(Log4j下载地址列表:http://www.apache.org/dyn/closer.cgi/logging/log4j/1.2.17/log4j-1.2.17.zip )
//关于log4j的使用请参看本博客另一篇文章《log4j使用快速入门 》,配置文件和log4j.jar在本例源码中有。
日志记录的三种实现:
1.不使用aop思想的实现
/**
* 客户端程序
* @author yanwushu
*
*/
public class Browser {
public static void main(String[] args) {
new Register().register("张三");
}
}
/**
*
* 注册机类
* @author yanwushu
*
*/
public class Register {
//一个日志记录器成员
Logger logger = Logger.getLogger(this.getClass().getName());
/**
* 注册方法
*/
public void register(String name ){
logger.info(name+"开始审核");
System.out.println("正在注册...");
logger.info(name+"注册完毕");
}
}
这样的方式,每个需要日志记录服务的方法都必须重复logger.info()这样的代码,且这些和业务逻辑无关的代码和业务逻辑紧紧耦合不利于维护,让程序员不能集中精力在业务的处理上。
2.使用静态代理模式实现Aop来实现日志服务
/**
* 客户端
* @author yanwushu
*
*/
public class Browser {
//使用静态代理模式实现Aop
public static void main(String[] args) {
Register register = new RegisterImpl();
RegisterProxy proxy = new RegisterProxy(register);
proxy.register("张三");
}
}
/**
* 注册机接口
* @author yanwushu
*
*/
public interface Register {
//定义注册服务
public void register(String name);
}
/**
* 注册机实现类
* @author yanwushu
*
*/
public class RegisterImpl implements Register {
@Override
public void register(String name) {
System.out.println(name+"正在注册");
}
}
/**
* 注册代理类
*/
public class RegisterProxy {
//一个日志记录器成员
Logger logger = Logger.getLogger(this.getClass().getName());
//一个注册接口的引用
private Register register;
public RegisterProxy(Register register){
this.register = register;
}
public void register(String name){
logger.debug("正在审核....");
register.register(name);
logger.debug("注册完毕");
}
}
这种实现的好处是把业务代码和与业务无关的记录日志的代码解耦。这样有利于代码的维护和程序员精力集中在业务的处理上。这样就已经实现了Aop的思想。在这里面向的切面就是日志记录这个横切关注点。不过使用静态代理的方式由一个坏处(也是静态代理模式的短板)就是当被代理类数量扩展的时候不得不扩展响应的代理类,进而造成代理类泛滥。
3.使用jdk 1.3之后的动态代理机制来实现Aop
/**
* 客户端代码
* @author yanwushu
*
*/
public class Browse {
public static void main(String[] args) {
//实例化日志代理类
LogProxy logProxy = new LogProxy(new RegisterImpl());
//动态获取代理实例
//参数:注册类的类装载器,被代理的接口,日志代理的实例
Register re = (Register)Proxy.newProxyInstance(RegisterImpl.class.getClassLoader(), RegisterImpl.class.getInterfaces(),logProxy);
re.register("张三");
}
}
/**
* 日志代理类,他可以代理一切需要日志输出服务的类
* 它实现了调用处理者接口
* @author yanwushu
*
*/
public class LogProxy implements InvocationHandler{
//一个日志记录器成员
private Logger logger = Logger.getLogger(this.getClass().getName());
//被代理者成员
private Object beProxy;
public LogProxy(Object beProxy){
this.beProxy = beProxy;
}
//实现调用方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result ;
logger.debug("正在审核");
result = method.invoke(beProxy, args);
logger.debug("注册完毕");
return result;
}
}
/**
* 注册机接口
* @author yanwushu
*
*/
public interface Register {
//定义注册服务
public void register(String name);
}
/**
* 注册机实现类
* @author yanwushu
*
*/
public class RegisterImpl implements Register {
@Override
public void register(String name) {
System.out.println(name+"正在注册");
}
}
Java 1.3之后的动态代理机制(参看java.lang.reflect.Proxy,java.lang.reflect.InvocationHandler)可以动态生成代理类(内部使用java的反射机制,参看java.lang.reflect包)。这样就弥补了静态代理的先天不足。不用担心代理类泛滥了。
- Aop_面向切面编程_思想理解资料01
- Aop_面向切面编程_思想理解资料02 .
- Aop_面向切面编程_思想理解资料03 . .
- Aop_面向切面编程(1)_思想理解
- Aop_面向切面编程(1)_思想理解
- AOP_面向切面编程
- 轻松理解AOP思想(面向切面编程)
- Aop_面向切面编程(2)_spring的aop实现
- AOP面向切面编程思想的原理(简单理解)
- 面向切面编程 理解
- AOP (面向切面编程)思想
- 面向切面编程_百度百科
- 面向切面编程(AOP)的理解
- 面向切面编程(AOP)的理解
- 面向切面编程(AOP)的理解
- 面向切面编程(AOP)的理解
- 面向切面编程(AOP)的理解
- 轻松理解AOP(面向切面编程)
- 三星平台SD/MMC驱动分析
- QT的Graphics View柜架(2/3)
- http://tldp.org/LDP/Bash-Beginners-Guide/html/index.html
- 关于短信猫MyMondem.SetThreadMode报错的解决方案
- 2013年11月6日
- Aop_面向切面编程_思想理解资料01
- QT的Graphics View柜架(3/3)
- 技巧: 使用truss、strace或ltrace诊断软件的"疑难杂症"
- 安装 配置 初次体验gradle
- Linux下select, poll和epoll IO模型的详解
- 在本机配置IIS步骤和注意事项
- Android 4.4 WebView重大改动:由Chromium驱动 支持HTML5和CSS新特性
- w7+eclipse +ndk9 NDK开发 hellow ndk 笔记(c调用java)
- 开通第一天