才开始学习AOP功能,并成功输出了Hello World了,哈哈,成功迈出第一步。
在该例子中,我们先编写一个类简单输出World,然后利用AOP,我们在程序运行时,让这个类的实例输出“Hello World!"。
代码清单1:MessageWriter类
package com.enyes.heart.java.aop.simple;
public class MessageWriter
{
public void writeMessage()
{
System.out.print("World");
}
}
MessageWriter类功能一眼明了。它只有一个打印World到控制台的输出方法。我们打算增加一个通知给这个类,让它的writeMessage()方法输入”Hello World!“。
为了完整输出Hello World,我们需要在这个方法之前输出Hello,并在这个方法结束后输出!。AOP术语解释为:我们需要包围通知(around Advice),即包围连接点的通知。在这个实例中,连接点就是对writeMessage()方法的调用。如下MessageDecorator类实现包围通知。
代码清单2:MessageDecorator类。
package com.enyes.heart.java.aop.simple;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MessageDecorator implements MethodInterceptor
{
public Object invoke(MethodInvocation invocation)
throws Throwable
{
System.out.print("Hello ");
Object obj = invocation.proceed();
System.out.println("!");
return obj;
}
}
MethodInteceptor接口就是对方法调用连接点实现包围通知的AOP标准接口。MethodInvocation对象表示当前被通知的方法调用。我们使用这个类来控制具体什么时候进行方法调用,所以我们可以在方法调用之前进行逻辑操作,也可以在方法调用之后执行另外的操作。如上代码清单中,我们简单的输出Hello,然后调用目标方法,然后输入!。
最后将MessageDecorator通知织入代码中。MessageWriter为目标对象,然后为其创建一个代理,并让代理工厂(proxy Factory)织入MessageDecorator通知。
代码清单3:具体MessageDecorator织入通知。
package com.enyes.heart.java.aop.simple;
import org.springframework.aop.framework.ProxyFactory;
public class HelloWorldWeaver
{
public static void main(String[] args)
{
MessageWriter target = new MessageWriter();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.addAdvice(new MessageDecorator());
proxyFactory.setTarget(target);
MessageWriter proxy = (MessageWriter)proxyFactory.getProxy();
target.writeMessage();
System.out.println("");
proxy.writeMessage();
}
}
这里,最终的部分是我们用ProxyFactory类来创建一个目标对象的代理,同时织入通知。我们通过调用addAdvice()方法将MessageDecorator通知传给ProxyFactory,然后通过setTarget()方法设置织入的目标对象。设置好目标对象并加入了通知后,我们通过getProxy()方法获得一个代理,然后使用代理调用目标方法。最后我们比较两种不同方法的调用生成的结果。如下。
-------------------------------
World
Hello World!
--------------------------------
具体操作jar包支持如下说明:
1.aopalliance-1.0.jar AOP标准JAR
2.org.springframework.aop-3.1.2.RELEASE.jar Spring3.1.2 RELEASE版本的AOPjar,可在Spring官网下载完整jar包。
3.org.springframework.core-3.1.2.RELEASE.jar Spring核心包,AOP依赖该jar包。
4.commons-logging.jar Spring使用该包打印日志。
5.com.springsource.net.sf.cglib-2.1.3.jar CGLIB代理。如果缺少该包,错误信息如下:
Exception in thread "main" org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.
at org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(DefaultAopProxyFactory.java:67)
at org.springframework.aop.framework.ProxyCreatorSupport.createAopProxy(ProxyCreatorSupport.java:104)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:98)
at com.enyes.heart.java.aop.simple.HelloWorldWeaver.main(HelloWorldWeaver.java:15)
注:非cglib-2.1_3.jar包,如果使用该包,出错信息如下,然后你去查找asm包。。。
Exception in thread "main" java.lang.NoClassDefFoundError: org/objectweb/asm/Type
at net.sf.cglib.core.TypeUtils.parseType(TypeUtils.java:180)
at net.sf.cglib.core.KeyFactory.<clinit>(KeyFactory.java:66)
at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:69)
at org.springframework.aop.framework.Cglib2AopProxy.createEnhancer(Cglib2AopProxy.java:229)
at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:171)
at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:146)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:98)
at com.enyes.heart.java.aop.simple.HelloWorldWeaver.main(HelloWorldWeaver.java:15)
Caused by: java.lang.ClassNotFoundException: org.objectweb.asm.Type
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... 8 more
另:jar可通过网站findjar快速查找下载,不需要百度,在csdn使用积分下载,对于像我这样毫无积分的人来说完全杯具。