面向切面有什么好处? 某同胞提出“面向接口有什么好处” 嘿嘿 本人问下面向切面有什么好处! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 此回复为自动发出,仅用于显示而已,并无任何其他特殊作用楼主【zspsys】截止到2008-06-23 21:06:39的历史汇总数据(不包括此帖):发帖数:4 发帖分:161 结贴数:4 结贴分:161 未结数:0 未结分:0 结贴率:100.00% 结分率:100.00% 敬礼! spring不是有句话, 你只管做你的,我来负责其他的事,比如你想监控 testXX()方法, 一般的情况下,你需要在testXX()里面加入代码,用AOP的话, testXX()方法不需要动, 由AOP监控到test就记录下相关的日志应该是这样的,不错,是这样的....... 正在学习spring.对AOP正在研究中。不过有一个问题如果什么都是用xml来控制,扩展,那么debug是不是很困难,比如bean的变量名写错了大小写错了,路径错了。这些都不能debug 日志和权限。SPRING是个好东西! 从某一角度观察系统的快照,以了解系统某时的状况。可以是静态的可以是动态的。UML MODEING! AOP, Aspect-Oriented Programming AOP是一个概念,并没有设定具体语言的实现; 它能克服那些只有单继承特性语言的缺点(如Java) AOP 可以把一些方法中共有的东西给提取出来,用不着每一个方法都去写一遍。下面这个是使用 JDK 动态代理实现的 AOP,呵呵,一个小小的示例,我想具体的代码可能更能说明问题。方便起见全写在 AopTest.java 文件里了。JDK 的动态代理有个缺点,就是代理的类的必需有一个接口,如果没有接口的类是不能做的。因此我们不能对类实现标注 @Enhancement,呵呵,相当遗憾。Cglib 也能使用动态代理,功能比 JDK 内置的强大,而且并不需要接口。不过他们各有优缺点。import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class AopTest { public static void main(String[] args) { Before before = new Before() { public void before() { System.out.println("...before..."); } }; After after = new After() { public void after() { System.out.println("...after..."); } }; Hello hello = null; // 普通方法执行 System.out.println("-------------普通执行-------------"); hello = new HelloEnglish(); hello.sayHello("bao110908"); hello.sayHi("bao110908"); System.out.println(); // 切入方法执行前(前置增强) System.out.println("-------------前置增强-------------"); hello = HelloAopManager.getHelloProxy(new HelloEnglish(), before); hello.sayHello("bao110908"); hello.sayHi("bao110908"); // sayHi 方法没有标注 @Enhancement 所以不会进行代码切入 System.out.println(); // 切入方法执行后(后置增强) System.out.println("-------------后置增强-------------"); hello = HelloAopManager.getHelloProxy(new HelloEnglish(), after); hello.sayHello("bao110908"); hello.sayHi("bao110908"); System.out.println(); // 切入方法执行前和执行后(环绕增强) System.out.println("-------------环绕增强-------------"); hello = HelloAopManager.getHelloProxy(new HelloEnglish(), before, after); hello.sayHello("bao110908"); hello.sayHi("bao110908"); System.out.println(); }}@Retention(RetentionPolicy.RUNTIME)@interface Enhancement { }interface Hello { @Enhancement public void sayHello(String name); public void sayHi(String name);}class HelloChinese implements Hello { public void sayHello(String name) { System.out.println(name + ",您好"); } public void sayHi(String name) { System.out.println("哈啰," + name); }}class HelloEnglish implements Hello { public void sayHello(String name) { System.out.println("Hello, " + name); } public void sayHi(String name) { System.out.println("hi, " + name); }}class HelloAopManager { private HelloAopManager(){ } public static Hello getHelloProxy(Hello hello, Before before) { return getHelloProxy(hello, before, null); } public static Hello getHelloProxy(Hello hello, After after) { return getHelloProxy(hello, null, after); } public static Hello getHelloProxy(Hello hello, Before before, After after) { HelloHandler handler = new HelloHandler(); if(before != null) { handler.setBefore(before); } if(after != null) { handler.setAfter(after); } return handler.bind(hello); } }/** * 前置增强接口 */interface Before { public void before();}/** * 后置增强接口 */interface After { public void after();}class HelloHandler implements InvocationHandler { /** * 需要进行代理的实例 */ private Hello hello = null; /** * 前置增强 */ private Before before = null; /** * 后置增强 */ private After after = null; /** * InvocationHandler 接口的实现方法,进行动态代理 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 看看接口中方法是否标注了需要 Enhancement boolean b = method.isAnnotationPresent(Enhancement.class); if(!b){ // 没有标注的话,按原方法执行 return method.invoke(hello, args); } // 有标注的话,进行方法的前置和后置增强 if(before != null) { before.before(); } Object obj = method.invoke(hello, args); if(after != null) { after.after(); } return obj; } /** * 将传入的 Hello 与 InvocationHandler 进行绑定,以获得代理类的实例 * @param hello * @return */ public Hello bind(Hello hello) { this.hello = hello; Hello helloProxy = (Hello)Proxy.newProxyInstance( hello.getClass().getClassLoader(), hello.getClass().getInterfaces(), this ); return helloProxy; } public void setAfter(After after) { this.after = after; } public void setBefore(Before before) { this.before = before; }} 上面这个是我所理解的 AOP bao110908 ,您好,您让我多了解了些知识,谢谢哦 谢谢各位的指导~~最近比较忙 好几天没来CSDN了 呵呵,AOP是Spring最强大的功能,而Introduction(引入)确实AOP最强大的功能一般的前置、后置、环绕自己写个动态代理也可以实现,可是Introduction确实强大到可以给一个类或接口增加原本不存在的方法和属性怎么加?Cglib的动态代理强大到可以更改你编译好的class文件,在运行时向里面插入一些byte字节序列,大家都知道class文件包含了Java类运行的所有信息,连它都给改了,也不知道是好还是不好,太强大了就会过头怎么用?AOP的动态代理都是把原对象丢给一个代理工厂,工厂返回一个代理对象,对外而言似乎没有区别,可是经过工厂返回的代理对象已经拥有了原对象不具有的方法和属性AOP的好处?就像楼上几位说的那样,面向切面是对面向对象编程的良好辅助,在众多相通业务逻辑的情况下可以把繁琐的业务逻辑提取出来加到切面中,这样关注点比较击中在切面,另外切面应该也是可插拔的,即插即用! 谢谢 有所了解了 马上就要学spring了 一个很简单问题(如何把\转为/) 求公式脚本。或指点。多谢。 Java中int型越界问题 请问用java脚本如何定义一个多维数组? 关于JAVA程序发布的问题,一定给分,请从事JAVA编程工作的人解答 高分求,哪儿有正版的DB2下载? 怎样访问在.jar里的图片文件? 100分悬赏scwcd@Whiz最新完整版!一拿到货,马上付款 在XP中MySQL老是启动不了,怎么办呢? 有时候初装jdk之后,不用设路径就可以使用,而有时则不行(但不行时有时候重装jdk即可),这当如何解释? 字符串又糊涂了!~~ 关于序列化问题,举些例子
楼主【zspsys】截止到2008-06-23 21:06:39的历史汇总数据(不包括此帖):
发帖数:4 发帖分:161
结贴数:4 结贴分:161
未结数:0 未结分:0
结贴率:100.00% 结分率:100.00%
敬礼!
spring不是有句话, 你只管做你的,我来负责其他的事,比如你想监控 testXX()方法, 一般的情况下,你需要在testXX()里面加入代码,
用AOP的话, testXX()方法不需要动, 由AOP监控到test就记录下相关的日志应该是这样的,不错,是这样的.......
不过有一个问题
如果什么都是用xml来控制,扩展,那么debug是不是很困难,比如bean的变量名写错了
大小写错了,路径错了。这些都不能debug
日志和权限。SPRING是个好东西!
AOP, Aspect-Oriented Programming
它能克服那些只有单继承特性语言的缺点(如Java)
能说明问题。方便起见全写在 AopTest.java 文件里了。JDK 的动态代理有个缺点,就是代理的类的必需有一个接口,如果没有接口的类是不能做的。
因此我们不能对类实现标注 @Enhancement,呵呵,相当遗憾。Cglib 也能使用动态代理,功能比 JDK 内置的强大,而且并不需要接口。不过他们各有优缺点。import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class AopTest { public static void main(String[] args) {
Before before = new Before() {
public void before() {
System.out.println("...before...");
}
};
After after = new After() {
public void after() {
System.out.println("...after...");
}
};
Hello hello = null;
// 普通方法执行
System.out.println("-------------普通执行-------------");
hello = new HelloEnglish();
hello.sayHello("bao110908");
hello.sayHi("bao110908");
System.out.println();
// 切入方法执行前(前置增强)
System.out.println("-------------前置增强-------------");
hello = HelloAopManager.getHelloProxy(new HelloEnglish(), before);
hello.sayHello("bao110908");
hello.sayHi("bao110908"); // sayHi 方法没有标注 @Enhancement 所以不会进行代码切入
System.out.println();
// 切入方法执行后(后置增强)
System.out.println("-------------后置增强-------------");
hello = HelloAopManager.getHelloProxy(new HelloEnglish(), after);
hello.sayHello("bao110908");
hello.sayHi("bao110908");
System.out.println();
// 切入方法执行前和执行后(环绕增强)
System.out.println("-------------环绕增强-------------");
hello = HelloAopManager.getHelloProxy(new HelloEnglish(), before, after);
hello.sayHello("bao110908");
hello.sayHi("bao110908");
System.out.println();
}
}@Retention(RetentionPolicy.RUNTIME)
@interface Enhancement {
}interface Hello {
@Enhancement
public void sayHello(String name);
public void sayHi(String name);
}class HelloChinese implements Hello {
public void sayHello(String name) {
System.out.println(name + ",您好");
}
public void sayHi(String name) {
System.out.println("哈啰," + name);
}
}class HelloEnglish implements Hello {
public void sayHello(String name) {
System.out.println("Hello, " + name);
}
public void sayHi(String name) {
System.out.println("hi, " + name);
}
}class HelloAopManager {
private HelloAopManager(){
}
public static Hello getHelloProxy(Hello hello, Before before) {
return getHelloProxy(hello, before, null);
}
public static Hello getHelloProxy(Hello hello, After after) {
return getHelloProxy(hello, null, after);
}
public static Hello getHelloProxy(Hello hello, Before before, After after) {
HelloHandler handler = new HelloHandler();
if(before != null) {
handler.setBefore(before);
}
if(after != null) {
handler.setAfter(after);
}
return handler.bind(hello);
}
}/**
* 前置增强接口
*/
interface Before {
public void before();
}/**
* 后置增强接口
*/
interface After {
public void after();
}class HelloHandler implements InvocationHandler {
/**
* 需要进行代理的实例
*/
private Hello hello = null;
/**
* 前置增强
*/
private Before before = null;
/**
* 后置增强
*/
private After after = null; /**
* InvocationHandler 接口的实现方法,进行动态代理
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 看看接口中方法是否标注了需要 Enhancement
boolean b = method.isAnnotationPresent(Enhancement.class);
if(!b){
// 没有标注的话,按原方法执行
return method.invoke(hello, args);
}
// 有标注的话,进行方法的前置和后置增强
if(before != null) {
before.before();
}
Object obj = method.invoke(hello, args);
if(after != null) {
after.after();
}
return obj;
}
/**
* 将传入的 Hello 与 InvocationHandler 进行绑定,以获得代理类的实例
* @param hello
* @return
*/
public Hello bind(Hello hello) {
this.hello = hello;
Hello helloProxy = (Hello)Proxy.newProxyInstance(
hello.getClass().getClassLoader(),
hello.getClass().getInterfaces(),
this
);
return helloProxy;
}
public void setAfter(After after) {
this.after = after;
} public void setBefore(Before before) {
this.before = before;
}
}
Cglib的动态代理强大到可以更改你编译好的class文件,在运行时向里面插入一些byte字节序列,大家都知道class文件包含了Java类运行的所有信息,连它都给改了,也不知道是好还是不好,太强大了就会过头怎么用?
AOP的动态代理都是把原对象丢给一个代理工厂,工厂返回一个代理对象,对外而言似乎没有区别,可是经过工厂返回的代理对象已经拥有了原对象不具有的方法和属性AOP的好处?
就像楼上几位说的那样,面向切面是对面向对象编程的良好辅助,在众多相通业务逻辑的情况下可以把繁琐的业务逻辑提取出来加到切面中,这样关注点比较击中在切面,另外切面应该也是可插拔的,即插即用!