- 论坛徽章:
- 0
|
先不讨论AOP的各种名词,也不作各种AOP的比较,我将在例子中介绍各种名词。
1。先写一个javabean,就是target object。
package org.tatan.test;
public class MessageBean {
public void write() {
System.out.print("AOP example");
}
}
2。写一个AOP的advice类
MethodInterceptor是AOP联盟的标准接口,它是最简单最实用的连接点(joinpoint),实现了around advice ,你可以在他返回前调用target的方法。
package org.tatan.test;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MessageCode implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.print("this is a ");
Object returnValue = invocation.proceed();
return returnValue ;
}
}
3。把MessageCode advice weave 到proxy factory,proxy factory是整个架构的核心
先创建instance of MessageBean,然后创建代理的instance ,MessageCode advice 传递给的
addAdvice()方法,设置Target Object,调用getProxy()产生代理对象。
import org.springframework.aop.framework.ProxyFactory;
public class AOPExample {
public static void main(String[] args) {
MessageBean target = new MessageBean();
ProxyFactory pf = new ProxyFactory();
pf.addAdvice(new MessageCode());
pf.setTarget(target);
MessageBean proxy = (MessageBean) pf.getProxy();
//输出原始信息
target.write();
//输出代理对象调用的信息
proxy.write();
}
}
4。classpath中加入cglib-nodep-2.1_2.jar ,spring.jar,aopalliance.jar,commons-logging.jar
结果
AOP example
this is a AOP example
有人问我,为什末使用CGLIB proxy而不使用JDK Dynamic Proxies,这和spring aop使用的原则相关。
1.使用AOP的时候,尽可能的使用接口,而不是使用具体的类,这样就可以使用JDK Dynamic Proxies,
如果目标类没有实现接口,spring使用CGLIB生成目标类的子类。
下面给个例子
接口类
package org.tatan.test;
public interface Worker {
void doSomeWork(int numOfTimes);
}
目标类
package org.tatan.test;
public class WorkerBean implements Worker {
public void doSomeWork(int numOfTimes) {
for (int i = 0; i System.out.println("---->" + args);
}
System.out.println();
return returnValue;
}
}
运行
package org.tatan.test;
import org.springframework.aop.framework.ProxyFactory;
public class AOPExample2 {
public static void main(String[] args) {
Worker bean = getWorkerBean();
bean.doSomeWork(100000000);
}
private static Worker getWorkerBean() {
WorkerBean target = new WorkerBean();
ProxyFactory pf = new ProxyFactory();
pf.setTarget(target);
pf.addAdvice(new AroundAdvice());
pf.setInterfaces(new Class[]{Worker.class});
return (Worker) pf.getProxy();
}
}
如果调用了setInterfaces();[color="#000000"]就不要cglib了,使用[color="#000000"]JDK Dynamic Proxies,[color="#000000"]只是使用JDK Dynamic Proxies程序执行的效率比较低。
使用CGLIB的Frozen效率比标准的CGLIB效率高。
package org.tatan.test;
import org.springframework.aop.framework.ProxyFactory;
public class AOPExample2 {
public static void main(String[] args) {
Worker bean = getWorkerBean();
bean.doSomeWork(100000000);
}
private static Worker getWorkerBean() {
WorkerBean target = new WorkerBean();
ProxyFactory pf = new ProxyFactory();
pf.setTarget(target);
pf.addAdvice(new AroundAdvice());
// pf.setInterfaces(new Class[]{Worker.class});
pf.setFrozen(true);
[color="#000000"] return (Worker) pf.getProxy();
}
}
原则上使用CGLIB,因为既可以使用类,还可以使用接口,JDK proxy 只能代理口[color="#000000"]。
[color="#000000"]2.目标类的方法不能是final的,因为spring要生成目标类的子类,任何要advised的方法都要overide,所以不允许final method。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/11783/showart_58443.html |
|