`
finux
  • 浏览: 200274 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

cglib学习 (2)

    博客分类:
  • Java
阅读更多

昨天写的cglib学习留下个问题善未实践:

对cglib的总结中有写到:

“3. 该默认的constractor建议不要声明为private,毕竟,按照刚刚的方式来操作是会抛Error的哦;

 

对于第3点,把samples.Beans放在samples.Bean里面作为一个内部类,不知会是啥情况呀,呵呵。。。有点晚了,明儿再试试看~睡觉去罗”

 

今天试了下,将默认的constractor声明为private确实不行,不过,找到另一种方式来达到这样一个效果:

1. 控制其他的coder使用new创建被代理的类;

2. 使用一个工厂方法来创建被代理的类的实例;

 

达到上述效果可作如下要求:

1. 将要被代理的类声明为abstract;

2. 将要被代理的类的默认constractor声明为private;

3. 提供一个static newInstance()来创建被代理的类实例;

4. Enhancer.setSuperclass()创建一个匿名的内部类,且extends被代理的类;

 

下面就是这种方式的具体实现:

package cglib.test;

import java.lang.reflect.Method;

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

/**
 * 被代理的类声明为abstract
 * @author zhu
 *
 */
public abstract class Hello {
	/**
	 * constractor声明为private不让其他类继承
	 */
	private Hello() { }
	
	/**
	 * 一些接口/方法,可以声明为abstract好让将要创建的匿名的内部子类去实现
	 */
	public void sayHello(){ }
	
	/**
	 * 工厂方法提供唯一接口用于创建Hello的实例
	 * @return
	 */
	public static Hello newInstance() {
		Enhancer enhancer = new Enhancer();
		//创建匿名内部类并继承自cglib.test.Hello
		enhancer.setSuperclass(new Hello() {
			public void sayHello() {
				System.out.println("Hello, World~");
			}
		}.getClass());
		//需要拦截的类,可以选择不用内部类实现,这里偷懒用匿名类实现了~
		enhancer.setCallback(new MethodInterceptor() {
			public Object intercept(Object obj, Method method, Object[] args,
					MethodProxy proxy) throws Throwable {
				System.out.println("before " + method.getName() + "() invoke");
				Object result = proxy.invokeSuper(obj, args);
				System.out.println("after " + method.getName() + "() invoke");
				return result;
			}
		});
		//这里也偷情没有进行try/catch了
		return (Hello)enhancer.create();
	}
	
	public static void main(String[] args) {
		//just for test
		Hello hello = Hello.newInstance();
		hello.sayHello();
	}
}
 

呵呵。。。达到了要求的效果吧,只有一个入口即cglib.test.Hello.newInstance()来创建Hello的实例~

0
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics