几种AOP编程
来源:互联网 发布:账户到期 数据库 编辑:程序博客网 时间:2024/06/05 15:17
面向切面编程相信大家都熟悉这个词汇了,废话我就不说了。
1、java.lang.reflect.Proxy
用动态代理来生成一个接口对象,然后通过InvocationHandler来实现切面织入。
这个动态代理是利用ProxyGenerator.generateProxyClass根据接口生成二进制流(byte数组的形式),然后调用本地方法defineClass0加载这个byte数组,从而得到这个代理对象的Class对象。这个代理Class对象有一个构造方法,这个构造方法的参数是InvocationHandler。
然后再通过反射生成代理对象。代码示例如下
public static void main(String[] args) {final Monitor m=new Monitor("测试");Logging log=(Logging) Proxy.newProxyInstance(m.getClass().getClassLoader(), new Class[]{Logging.class}, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("do xxxxx");Object o=method.invoke(m, args);System.out.println("do xxxxx end");return o;}});log.log();}
interface Logging{public void log();}class Monitor implements Logging{public Monitor(String name){this.name=name;}private String name;@Overridepublic void log() {System.out.println(" logging:"+name);}}
结果:
do xxxxx logging:测试do xxxxx end
优点:使用简单。仅用jdk就能完成不需要其他jar
缺点:从Proxy的代码来看,他的aop编程是基于代码运行时生成代理,然后在这个代理上做切面织入的。而且每次调用方法,都会使用反射,所以性能上不太好。
2、AspectJ
AspectJ是基于在编译期将切面织入字节码文件的。所以对于AspectJ的aop来说,不存在大量反射影响性能的情况。
切面代码
public aspect BoundPerson { pointcut log(Person p) : call(public void Person.*(*))&&target(p); after(Person p) returning() : log(p){ System.out.println(thisJoinPoint.getSourceLocation()+" "+thisJoinPoint.getSignature().getName()); System.out.println("logging:"+p.getName()); }}被织入的对象
public class Person { private String name; public String getName(){ return name;} public void setName(String name){ this.name=name; } public static void main(String a[]){ new Person().setName("haha"); }}运行结果
Person.java:12 setNamelogging:hahaAspectJ的编程有自己的一套规范,对于java开发者来说不难掌握。AspectJ的编译器实际上就是运行一个java程序,将aspect文件加载后并解析。然后根据这个文件内容,去修改切面的字节码文件,来达到织入的效果。
优点:织入语言比较清晰容易掌握。因为是编译期织入,所以运行速度比较快。
缺点:需要AspectJ编译器,加入aspectj的相关jar包才能使用。
3、CGlLib(asm包装)
这个在spring、hibernate等开源框架都有使用。
public static void main(String[] args) {final Dog dog=new Dog();Enhancer en=new Enhancer();en.setSuperclass(Dog.class);en.setCallback(new MethodInterceptor() {@Overridepublic Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {System.out.println("begin xxxx");Object o=method.invoke(dog, args);return o;}});Dog d=(Dog)en.create();d.say();}
class Dog {public void say(){System.out.println("dog say: 汪汪汪");}}运行结果
begin xxxxdog say: 汪汪汪CGlib是对asm的一个包装。asm是一个优秀的字节码框架。CGlib在生成代理时,会利用asm来生成一个被代理对象的子类字节码流,然后通过加载这个字节码流,来生成代理类。这么做的好处就是不需要被代理类实现接口。通过反编译CGlib的动态代理字节码文件,会发现代理对象的方法调用不是通过反射来完成的,这样会在性能上有较大提升。
优点:稳定、简单、容易使用。比java.lang.reflect.Proxy性能好。不需要实现接口。
4、其他修改字节码文件框架,asm、javassit、bcel等
这几种使用起来不方便,就不介绍了
0 0
- 几种AOP编程
- Aop 几种应用实例
- aop的几种用法
- AOP系列:.NET中AOP的几种实现方案
- spring AOP配置的几种方法
- Spring中AOP几种通知
- Spring AOP的几种实现方式
- spring aop的几种配置方式:
- AOP的实现的几种方式
- Spring 的几种AOP通知
- Spring AOP的几种实现方式
- Spring AOP几种方式的使用
- AOP编程
- AOP编程
- AOP编程
- AOP编程
- AOP编程
- AOP编程
- Matplotlib Tutorial
- 交换机基础
- IOS自定义View使用block实现点击事件
- 久了,梦
- Spark 快速理解
- 几种AOP编程
- 代理模式
- Count and Say Java
- UVA 1594 - Ducci Sequence
- AjaxControlToolkit中CalendarExtender日历控件的用法
- Informix触发器实例
- 数字金额转换成汉字
- 脏读,不可重复读,幻象读
- Informatica元数据库解析