Spring AOP 的 Hello World

        才开始学习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使用积分下载,对于像我这样毫无积分的人来说完全杯具。




 
 
 
 

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值