Spring AOP 的 Hello World

来源:互联网 发布:淘宝整点秒杀是真的吗 编辑:程序博客网 时间:2024/06/07 12:07

        才开始学习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()方法获得一个代理,然后使用代理调用目标方法。最后我们比较两种不同方法的调用生成的结果。如下。

-------------------------------

WorldHello 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/Typeat 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.Typeat 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使用积分下载,对于像我这样毫无积分的人来说完全杯具。