Java动态代理的作用

renlei413326889 2008-12-07 05:51:41
如题,Java中动态代理有点迷惑,在网上看到的代码都是如下这类:
//定义接口
public interface Foo
{
void doAction();
}
//实现一
public class FooImpl implements Foo
{
public FooImpl()
{
}

public void doAction()
{
System.out.println("in FooImp1.doAction()");
}
}
//实现二
public class FooImpl2 implements Foo
{
public FooImpl2()
{
}
public void doAction()
{
System.out.println("in FooImp2.doAction()");
}

}
//代理类
public class DynamicSubject implements InvocationHandler
{
private Object sub;

public DynamicSubject()
{
}

public DynamicSubject(Object obj)
{
sub = obj;
}

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
System.out.println("before calling " + method);

method.invoke(sub, args);

System.out.println("after calling " + method);

return null;
}

}
//测试
public class Demo
{
public static void main(String[] args)
{

// 1.通用的动态代理实现

CommonInvocationHandler handler = new CommonInvocationHandler();

Foo f;

// 2.接口实现1

handler.setTarget(new FooImpl());

f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),

new Class[] { Foo.class },

handler);

f.doAction();

// 3.接口实现2

handler.setTarget(new FooImpl2());

f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),

new Class[] { Foo.class },

handler);

f.doAction();
}
}
----------->>也就是面向接口编程,完全可以写一个工厂类实现的,为什么要采用这个方式,如:

class Factory{
Foo fo ;
public Factory(Foo fo){
this.fo = fo;
}
public Foo getInstence(){
return fo;
}
}
然后创建Factory对象
=============》》 有什么差别么??

...全文
3296 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
itopme 2011-12-13
  • 打赏
  • 举报
回复
学习. 不懂看看这篇文章 http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html
sqp907372108 2011-05-07
  • 打赏
  • 举报
回复
学习了,呵呵
OrchidPa 2010-12-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lshy168 的回复:]
你要知道动态代理的主要作用是什么,以下是我个人理解动态代理:
动态代理的主要作用就是:实现了日志和业务的分开,也就是某个类只是要提供了某些业务,比如银行取款业务。
这个类实现了取款业务的同时也需要实现日志功能,如果不用动态代理的话,那么由此一来该类代码里面已经额外地添加了自己不该添加的日志功能能代码。所以我们就得使用动态代理把它的业务代码和日志功能代码分开。所以用到了动态代理概念,spr……
[/Quote]

讲的很对。

动态代理是对面向对象思想的一种补充。因为面向对象思想强调的是抽象,是本质,是主要方面。也因此它对次要方面、非本质的东西缺乏科学的理论依据,当然,都做在一起也没有什么大错。而动态代理就可以把这些次要的、非本质的东西再按照面向对象思想进行归类,当然,它要有前提,因为主要确定次要。
qipanpan 2010-08-17
  • 打赏
  • 举报
回复
应该它最大优越性在于,方法执行前后,能调用函数,做下判断吧
wqb127 2008-12-30
  • 打赏
  • 举报
回复
代理就像是你找对象的中介机构吧!呵呵呵
thomas.he 2008-12-27
  • 打赏
  • 举报
回复
代理
lusi102121 2008-12-24
  • 打赏
  • 举报
回复
被代理的对象调用方法前后做一些事情 例如事务 日志
时光瞄 2008-12-11
  • 打赏
  • 举报
回复
动态代理主要是在运行时期创建一个实现一组特定接口的代理类,拦截对目标对象方法的调用...
lshy168 2008-12-08
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 renlei413326889 的回复:]
谢谢你的解答!虽然我学习ssh框架并能运用,但原理还不很清楚,看样子的慢慢来的 可以加好友么?
[/Quote]
技术交流,可以的。
renlei413326889 2008-12-08
  • 打赏
  • 举报
回复
谢谢你的解答!虽然我学习ssh框架并能运用,但原理还不很清楚,看样子的慢慢来的 可以加好友么?
lshy168 2008-12-08
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 renlei413326889 的回复:]
那使用包装模式也可以做到吧?就像IO流 也是额外添加功能的 有什么区别么 , 还是有点迷惑的地方
[/Quote]
动态代理在 Spring 里面的aop不是那么好理解的,你久了就会慢慢的理解了,编程这东西就是这样的,你现在迷茫没什么关系的,久了我保证你会明白的。就上面已经解释清楚了。
renlei413326889 2008-12-08
  • 打赏
  • 举报
回复
那使用包装模式也可以做到吧?就像IO流 也是额外添加功能的 有什么区别么 , 还是有点迷惑的地方
lshy168 2008-12-08
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 lshy168 的回复:]
你要知道动态代理的主要作用是什么,以下是我个人理解动态代理:
动态代理的主要作用就是:实现了日志和业务的分开,也就是某个类只是要提供了某些业务,比如银行取款业务。
这个类实现了取款业务的同时也需要实现日志功能,如果不用动态代理的话,那么由此一来该类代码里面已经额外地添加了自己不该添加的日志功能能代码。所以我们就得使用动态代理把它的业务代码和日志功能代码分开。所以用到了动态代理概念,spring里面…
[/Quote]
还有补充,实现了业务和日志的分离也带来很好的独立性,你在开发时一般都是需要日志功能的,但是你开发完毕后有的日志你不想打印出来怎么办呢?所以动态代理给了你很好的设计思想。
lshy168 2008-12-08
  • 打赏
  • 举报
回复
你要知道动态代理的主要作用是什么,以下是我个人理解动态代理:
动态代理的主要作用就是:实现了日志和业务的分开,也就是某个类只是要提供了某些业务,比如银行取款业务。
这个类实现了取款业务的同时也需要实现日志功能,如果不用动态代理的话,那么由此一来该类代码里面已经额外地添加了自己不该添加的日志功能能代码。所以我们就得使用动态代理把它的业务代码和日志功能代码分开。所以用到了动态代理概念,spring里面的AOP就是一个很好的例子。


希望对你 有帮助!!!
lshy168 2008-12-08
  • 打赏
  • 举报
回复
你要知道动态代理的主要作用是什么,以下是我个人理解动态代理:
[color=#f0000]动态代理的主要作用就是:实现了日志和业务的分开,也就是某个类只是要提供了某些业务,比如银行取款业务。
这个类实现了取款业务的同时也需要实现日志功能,如果不用动态代理的话,那么由此一来该类代码里面已经额外地添加了自己不该添加的日志功能能代码。所以我们就得使用动态代理把它的业务代码和日志功能代码分开。所以用到了动态代理概念,spring里面的AOP就是一个很好的例子。[/color]

希望对你 有帮助!!!
  • 打赏
  • 举报
回复
可以实现 AOP 啊,可以运行一下下面的代码,也是原来回复过,粘过来的,呵呵(为了便于调试全部写在一个文件里了)

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class AopTest {

public static void main(String[] args) {

Before before = new Before() {
public void before() {
System.out.println("...before...");
}
};

After after = new After() {
public void after() {
System.out.println("...after...");
}
};

Hello hello = null;

// 普通方法执行
System.out.println("-------------普通执行-------------");
hello = new HelloEnglish();
hello.sayHello("bao110908");
hello.sayHi("bao110908");
System.out.println();

// 切入方法执行前(前置增强)
System.out.println("-------------前置增强-------------");
hello = HelloAopManager.getHelloProxy(new HelloEnglish(), before);
hello.sayHello("bao110908");
hello.sayHi("bao110908"); // sayHi 方法没有标注 @Enhancement 所以不会进行代码切入
System.out.println();

// 切入方法执行后(后置增强)
System.out.println("-------------后置增强-------------");
hello = HelloAopManager.getHelloProxy(new HelloEnglish(), after);
hello.sayHello("bao110908");
hello.sayHi("bao110908");
System.out.println();

// 切入方法执行前和执行后(环绕增强)
System.out.println("-------------环绕增强-------------");
hello = HelloAopManager.getHelloProxy(new HelloEnglish(), before, after);
hello.sayHello("bao110908");
hello.sayHi("bao110908");
System.out.println();
}
}



@Retention(RetentionPolicy.RUNTIME)
@interface Enhancement {
}

interface Hello {
@Enhancement
public void sayHello(String name);
public void sayHi(String name);
}

class HelloChinese implements Hello {
public void sayHello(String name) {
System.out.println(name + ",您好");
}
public void sayHi(String name) {
System.out.println("哈啰," + name);
}
}

class HelloEnglish implements Hello {
public void sayHello(String name) {
System.out.println("Hello, " + name);
}
public void sayHi(String name) {
System.out.println("hi, " + name);
}
}

class HelloAopManager {
private HelloAopManager(){
}

public static Hello getHelloProxy(Hello hello, Before before) {
return getHelloProxy(hello, before, null);
}

public static Hello getHelloProxy(Hello hello, After after) {
return getHelloProxy(hello, null, after);
}

public static Hello getHelloProxy(Hello hello, Before before, After after) {
HelloHandler handler = new HelloHandler();
if(before != null) {
handler.setBefore(before);
}
if(after != null) {
handler.setAfter(after);
}
return handler.bind(hello);
}
}

/**
* 前置增强接口
*/
interface Before {
public void before();
}

/**
* 后置增强接口
*/
interface After {
public void after();
}

class HelloHandler implements InvocationHandler {

/**
* 需要进行代理的实例
*/
private Hello hello = null;

/**
* 前置增强
*/
private Before before = null;

/**
* 后置增强
*/
private After after = null;

/**
* InvocationHandler 接口的实现方法,进行动态代理
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 看看接口中方法是否标注了需要 Enhancement
boolean b = method.isAnnotationPresent(Enhancement.class);
if(!b){
// 没有标注的话,按原方法执行
return method.invoke(hello, args);
}
// 有标注的话,进行方法的前置和后置增强
if(before != null) {
before.before();
}
Object obj = method.invoke(hello, args);
if(after != null) {
after.after();
}
return obj;
}

/**
* 将传入的 Hello 与 InvocationHandler 进行绑定,以获得代理类的实例
* @param hello
* @return
*/
public Hello bind(Hello hello) {
this.hello = hello;
Hello helloProxy = (Hello)Proxy.newProxyInstance(
hello.getClass().getClassLoader(),
hello.getClass().getInterfaces(),
this
);
return helloProxy;
}

public void setAfter(After after) {
this.after = after;
}

public void setBefore(Before before) {
this.before = before;
}
}


xiashengnan110 2008-12-07
  • 打赏
  • 举报
回复
看了还是很迷糊!
bzwm 2008-12-07
  • 打赏
  • 举报
回复
mark。

等个能解释清楚的人出现。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧