java动态代理技术解疑

为何选择动态代理?相对于静态代理有什么优势?

优势主要体现在采用反射技术实现,这样我们就不用为每一个被代理对象编写一个代理类,并且被代理的业务逻辑也可以放在一块集中处理。

代码主要的区别:

静态代理中的代理类必须要自己实现。并且持有相应的被代理的的类型。

interface Person {
	public void say();
}

class Teacher implements Person {

	@Override
	public void say() {
		// TODO Auto-generated method stub
		System.out.println(" my name is eric");
	}

}

class PersonProxy implements Person {
	private Person person;

	public PersonProxy(Person person) {
		this.person = person;
	}

	@Override
	public void say() {
		// TODO Auto-generated method stub
		beforeSay();
		person.say();
		afterSay();
	}

	private void beforeSay() {
		System.out.println("before");
	}

	private void afterSay() {
		System.out.println("after");
	}
}

  动态代理中的主要起作用的handler,而handler中的类型却可以设置为object,因为我们采用的反射机制具体类型可以在运行中得知。所以handler能够处理一切继承自object的类。

class Handler implements InvocationHandler {
	public Handler(Object person) {
		this.obj = person;
	}

	private Object obj;

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		beforeSay();
		Object ob = method.invoke(obj, args);
		afterSay();
		return ob;
	}

	private void beforeSay() {

		System.out.println("hi,all");
	}

	private void afterSay() {

		System.out.println("thanks");
	}
}

  

Teacher t1 = new Teacher();
		Handler handler = new Handler(t1);
		Person t2 = (Person) Proxy.newProxyInstance(
				ProxyTest.class.getClassLoader(),
				t1.getClass().getInterfaces(), handler);
		t2.say();
		Dog d1 = new Dog();
		Handler handler2 = new Handler(d1);
		Animal d2 = (Animal) Proxy.newProxyInstance(
				ProxyTest.class.getClassLoader(),
				d1.getClass().getInterfaces(), handler2);
		d2.hawl();

  在上述情况下,我们解耦了被代理对象的类型,但是却发现每次还需要创建handler,创建proxy对象,如果想要解决这个问题我们可以采用工厂模式来解决这个问题。

class ProxyFactory {
	
	public static Object getProxy(final Object obj) {
		InvocationHandler handler = new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				// TODO Auto-generated method stub
				doBefore();
				Object ob = method.invoke(obj, args);
				doAfter();
				return ob;
			}
			private void doBefore() {
				System.out.println("before");
			}
			private void doAfter() {
				System.out.println("after");
			}
		};
		return Proxy.newProxyInstance(ProxyFactory.class.getClassLoader(), obj
				.getClass().getInterfaces(), handler);
	}
}

  这样之后,我们在需要代理对象的场合时就非常方便了。不需要显示的创建handler,不需要显示的创建proxy对象。只需要传递被代理的对象,所有其他的问题交由反射来解决。

Dog d1 = new Dog();
		Animal d2 = (Animal) ProxyFactory.getProxy(d1);
		d2.hawl();

  

 

posted @ 2014-07-30 14:26  menglgcn  阅读(77)  评论(0)    收藏  举报