实际应用中,需要代理的类可能
没有实现接口,那么就不能用 JDK 来实现动态代理,可以使用 CGlib 来实现。
CGlib 动态代理:
package aop.test.factory;
import java.lang.reflect.Method;
import output.test.impl.HelloBean;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGlibProxyFactory implements MethodInterceptor {
private Object targetObject; // 代理的目标对象
public Object createProxyInstance(Object targetObject) {
this. targetObject = targetObject;
Enhancer enhancer = new Enhancer(); // 该类用于生成代理对象
enhancer.setSuperclass( this. targetObject.getClass()); // 设置父类,会重写所有的非final类型。
enhancer.setCallback( this); // 设置回调用对象为本身,调用对象必须实现接口 MethodInterceptor 中的 intercept()
return enhancer.create();
}
public Object intercept(Object proxy, Method method, Object[] args ,
MethodProxy methodProxy) throws Throwable {
HelloBean bean = (HelloBean) targetObject; // 如果是 jdk 代理,则这里写的是目标对象的接口,而不是其本身。详见课时15.
if( bean.getName()== null){
return null;
}
return methodProxy.invoke( this. targetObject, args);
}
}
其中, HelloBean 类如下。注意,这个类
没有实现接口。
package output.test.impl;
import output.test.Hello;
public class HelloBean{
private String name = null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public HelloBean(){}
public HelloBean(String name) {
super();
this.name = name;
}
public void output() {
System.out.println("name="+name);
}
}
测试代理的函数:
public void testCGlib() {
CGlibProxyFactory proxy = new CGlibProxyFactory();
HelloBean hello = (HelloBean) proxy.createProxyInstance( new HelloBean( "Gong"));
hello.output();
}
CGlib 可以适用于有接口或无接口的类。因此,如果 HelloBean 类实现了接口,也完全没问题。但是 JDK 只适用于实现了接口的类。