AOP(面向方面编程)是一种新的编程技术,它能够将那些本不应该纠缠在一起的任务分离开,从而为程序提供更好的封装性和互操作性.
AOP是通过代理机制实现的.
代理是指为其他对象提供一种代理以控制对这个对象的访问.
代理分为三种:
1.静态代理,代理对象必须实现目标对象的接口,且一个接口只服务于一种类型的目标对象。
2.JDK动态代理,代理对象必须实现java.lang.reflect.InvacationHandler接口,只能为接口创建代理实例。
3.CGLib动态代理,使用非常底层的字节码技术,可以为任何对象创建代理.
以下是目标对象接口和目标对象.
目标对象接口如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
package
org.test.spring.aop;
public
interface
IHello
{
public
void
hello(String name);
}
目标对象如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
package
org.test.spring.aop;
public
class
HelloSpeaker
implements
IHello
{
public
void
hello(String name)
{
System.out.print(
"
Hi,
"
+
name);
}
}
一.静态代理
静态代理比较容易理解,静态代理其实很容易理解,静态代理其实就是个装饰器而已.
让代理对象也实现目标对像的接口,这样做的目的是让使用者在使用代理对象时感觉不到代理对象的存在.
代理对象如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
package
org.test.spring.aop;
public
class
HelloSpeakerProxy
implements
IHello
{
private
IHello helloSpeaker;
public
HelloSpeakerProxy(IHello helloSpeaker)
{
this
.helloSpeaker
=
helloSpeaker;
}
public
void
hello(String name)
{
this
.helloSpeaker.hello(name);
System.out.println(
"
, welcome to our pub.
"
);
}
public
static
void
main(String[] args)
{
IHello helloSpeaker
=
new
HelloSpeaker();
IHello proxy
=
new
HelloSpeakerProxy(helloSpeaker);
proxy.hello(
"
Huy Vanpon
"
);
}
}
二.JDK动态代理
所谓Dynamic Proxy是这样一种class:它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->
package
org.test.spring.aop;
import
java.lang.reflect.InvocationHandler;
import
java.lang.reflect.Method;
import
java.lang.reflect.Proxy;
public
class
HelloSpeakerProx
implements
InvocationHandler
{
private
Object target;
public
Object invoke(Object proxy, Method method, Object[] parameters)
throws
Throwable
{
Object object
=
null
;
try
{
object
=
method.invoke(target, parameters);
System.out.println(
"
, welcome to our pub.
"
);
}
catch
(Exception e)
{
e.printStackTrace();
}
return
object;
}
/**
* <p>
* 这个方法用于得到代理对象
* </p>
*
*
@param
target
* 目标对象
*
@return
result(Object)代理对象
*/
public
Object getProxy(Object target)
{
this
.target
=
target;
/**
* newProxyInstance(ClassLoader loader, Class<?>[] interfaces,
* InvocationHandler invocationHandler) loader: 定义代理类的加加载器(目标类的加载器)
* interfaces: 代理类要实现的接口列表 invocationHandler: 指派方法调用的调用处理程序
*/
return
Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this
);
}
public
static
void
main(String[] args)
{
IHello proxy
=
(IHello)
new
HelloSpeakerProx()
.getProxy(
new
HelloSpeaker());
proxy.hello(
"
Huy Vanpon
"
);
}
}
三.CGLib动态代理
使用jdk创建代理有一个限制,即它只能为接口创建代理实例.CGLib使用非常底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的拦截技术,并顺势织入横切逻辑.
运行这个例子,一定要记得导入CGLib相应的包哦..
package
org.test.spring.aop;

import
java.lang.reflect.Method;

import
net.sf.cglib.proxy.Enhancer;
import
net.sf.cglib.proxy.MethodInterceptor;
import
net.sf.cglib.proxy.MethodProxy;

public
class
HelloSpeakerPro
implements
MethodInterceptor

{
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz)

{
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object object, Method method, Object[] args,
MethodProxy proxy) throws Throwable

{
Object result = null;
result = proxy.invokeSuper(object, args);
System.out.println(", welcome to our pub.");
return result;
}
public static void main(String[] args)

{
HelloSpeakerPro helloSpeakerPro = new HelloSpeakerPro();
HelloSpeaker helloSpeaker = (HelloSpeaker) helloSpeakerPro
.getProxy(HelloSpeaker.class);
helloSpeaker.hello("Huy Vanpon");
}
}