一个程序问题,广大大牛们可不可以用动态代理模式实现(调用method方法后不结束main方法)

public class Test {/** * @param args */public ... public class Test {

/**
 * @param args
 */

public static void main(String[] args) {
// TODO Auto-generated method stub
int a=10;
int b=10;

method(a,b);
System.out.println("a="+a);
System.out.println("b="+b);
}
//如何实现当method方法被调用之后打印a=100,b=200?

}
展开
 我来答
lalakj777
2017-02-13 · 超过37用户采纳过TA的回答
知道答主
回答量:57
采纳率:0%
帮助的人:31.7万
展开全部
当然代理模式中,用的最广泛的,用的最多的是 动态代理模式。

动态代理:就是实现阶段不用关系代理是哪个,而在运行阶段指定具体哪个代理。

抽象接口的类图如下:

      --图来自设计模式之禅

所以动态代理模式要有一个InvocationHandler接口 和 GamePlayerIH实现类。其中 InvocationHandler是JD提供的动态代理接口,对被代理类的方法进行代理。

代码实现如下

抽象主题类或者接口:

复制代码
1 package com.yemaozi.proxy.dynamic;
2
3 /*
4 * 动态代理:就是实现阶段不用关系代理是哪个,而在运行阶段指定具体哪个代理。
5 */
6 public interface IGamePlayer {
7 //登录游戏
8 public void login(String username, String password);
9
10 //击杀Boss
11 public void killBoss();
12
13 //升级
14 public void upGrade();
15 }
复制代码

需要被代理类:

复制代码
1 package com.yemaozi.proxy.dynamic;
2
3 public class GamePlayer implements IGamePlayer {
4
5 private String name = "";
6
7 public GamePlayer(String name){
8 this.name = name;
9 }
10
11 public void login(String username, String password) {
12 System.out.println("登录名为 "+username+" 进入游戏," + name + " 登录成功!");
13 }
14
15 public void killBoss() {
16 System.out.println(this.name + " 击杀了Boss!");
17 }
18
19 public void upGrade() {
20 System.out.println(this.name + "升级了!");
21 }
22
23 }
复制代码

动态代理处理器类:

复制代码
1 package com.yemaozi.proxy.dynamic;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5
6 public class GamePlayerInvocationHandler implements InvocationHandler{
7
8 //被代理的对象
9 private Object obj;
10
11 //将需要代理的实例通过处理器类的构造方法传递给代理。
12 public GamePlayerInvocationHandler(Object obj){
13 this.obj = obj;
14 }
15
16 public Object invoke(Object proxy, Method method, Object[] args)
17 throws Throwable {
18 Object result = null;
19 if("login".equalsIgnoreCase(method.getName())){
20 //这个在主题方法不受任何影响的情况下,在主题方法前后添加新的功能,或者增强主题方法,
21 //从侧面切入从而达到扩展的效果的编程,就是面向切面编程(AOP Aspect Oriented Programming)。
22 //AOP并不是新技术,而是相对于面向对象编程的一种新的编程思想。在日志,事务,权限等方面使用较多。
23 System.out.println("代理登录游戏!");
24 result = method.invoke(this.obj, args);
25 return result;
26 }
27 result = method.invoke(this.obj, args);
28 return result;
29 }
30
31 }
复制代码
由于代理是动态产生的,所以不需要再声明代理类。

动态代理场景类:

复制代码
package com.yemaozi.proxy.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Client {
public static void main(String[] args) {
IGamePlayer gp = new GamePlayer("张三");
InvocationHandler gpHandler = new GamePlayerInvocationHandler(gp);
//获取真实主题类的ClassLoader
ClassLoader classLoader = gp.getClass().getClassLoader();
//动态产生一个代理者。
Class<?>[] cls = new Class[]{IGamePlayer.class};
IGamePlayer proxyGp = (IGamePlayer) Proxy.newProxyInstance(classLoader, cls, gpHandler);
proxyGp.login("zhangsan", "123456");
proxyGp.killBoss();
proxyGp.upGrade();
}
}

执行结果:
代理登录游戏!
登录名为 zhangsan 进入游戏,张三 登录成功!
张三 击杀了Boss!
张三升级了!

//在此,我们没有创建代理类,但是确实有代理类帮我们完成事情。
复制代码
其中,在此代理模式中,不仅代理是动态产生的(即在运行的时候生成),而且还在代理的时候,也增加了一些处理。在此处增加的处理,其实就是另一种编程思想-----面向切面编程思想(AOP Aspect Oriented Programming)。

带有AOP的动态代理模式类图:

        --图来自设计模式之禅

从上图中,可以看出有两个相对独立的模块(Subject和InvocationHandler)。动态代理实现代理的职责,业务逻辑Subject实现相关的逻辑功能,两者之间没有必然的相互耦合的关系。然而,通知Advice从另一个切面切入,最终在上层模块就是Client耦合,完成逻辑的封装。

代码清单如下

抽象主题或者接口:

复制代码
1 package com.yemaozi.proxy.dynamic_aop;
2
3 public interface Subject {
4 public void doSomething(String str);
5 //...可以多个逻辑处理方法。。。
6 }
复制代码

真实主题:

复制代码
1 package com.yemaozi.proxy.dynamic_aop;
2
3 public class RealSubject implements Subject{
4
5 public void doSomething(String str) {
6 //do something...
7 System.out.println("do something..." + str);
8 }
9
10 }
复制代码

通知接口:

复制代码
1 package com.yemaozi.proxy.dynamic_aop;
2
3 //通知接口及定义、
4 public interface IAdvice {
5 public void exec();
6 }
复制代码

前置通知:

复制代码
1 package com.yemaozi.proxy.dynamic_aop;
2
3 public class BeforeAdvice implements IAdvice {
4 //在被代理的方法前来执行,从而达到扩展功能。
5 public void exec() {
6 System.out.println("前置通知被执行!");
7 }
8 }
复制代码

后置通知:

复制代码
1 package com.yemaozi.proxy.dynamic_aop;
2
3 public class AfterAdvice implements IAdvice {
4
5 //在被代理的方法后来执行,从而达到扩展功能。
6 public void exec() {
7 System.out.println("后置通知被执行!");
8 }
9 }
复制代码

动态代理的处理器类:

所有的方法通过invoke方法类实现。

复制代码
1 package com.yemaozi.proxy.dynamic_aop;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5
6 public class MyInvocationHandler implements InvocationHandler {
7
8 //被代理的对象
9 private Subject realSubject;
10 //通过MyInvocationHandler的构造方法将被代理对象传递过来。
11 public MyInvocationHandler(Subject realSubject){
12 this.realSubject = realSubject;
13 }
14 //执行被代理类的方法。
15 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
16 //在执行方法前,执行前置通知。
17 IAdvice beforeAdvice = new BeforeAdvice();
18 beforeAdvice.exec();
19 Object result = method.invoke(this.realSubject, args);
20 //在执行方法后,执行后置通知。
21 IAdvice afterAdvice = new AfterAdvice();
22 afterAdvice.exec();
23 //前置通知,和后置通知,都是要看具体实际的业务需求来进行添加。
24 return result;
25 }
26
27 }
复制代码

动态代理类:

复制代码
1 package com.yemaozi.proxy.dynamic_aop;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Proxy;
5
6 public class DynamicProxy {
7
8 /**
9 * public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler handler)
10 * loader:
11 * 一个ClassLoader对象,定义了由哪个ClassLoader对象,来对生产的代理进行加载。
12 * interfaces:
13 * 一个Interfaces数组,表示我将要给我所代理的对象提供一组什么样的接口,
14 * 如果提供一组接口给它,那么该代理对象就宣称实现了该接口,从而可以调用接口中的方法。
15 * 即,查找出真是主题类的所实现的所有的接口。
16 * handler:
17 * 一个InvocationHandler对象,表示当我这个动态代理对象在调用方法时,会关联到该InvocationHandler对象。
18 * 该InvocationHandler与主题类有着关联。
19 */
20 public static <T> T newProxyInstance(ClassLoader classLoader, Class<?>[] interfaces, InvocationHandler handler){
21 @SuppressWarnings("unchecked")
22 T t = (T) Proxy.newProxyInstance(classLoader, interfaces, handler);
23 return t;
24 }
25 }
复制代码
从动态的产生动态代理类。

动态代理场景类:

复制代码
1 package com.yemaozi.proxy.dynamic_aop;
2
3 import java.lang.reflect.InvocationHandler;
4
5 public class AOPClient {
6
7 public static void main(String[] args) {
8 Subject realSubject = new RealSubject();
9 InvocationHandler handler = new MyInvocationHandler(realSubject);
10 ClassLoader classLoader = realSubject.getClass().getClassLoader();
11 Class<?>[] interfaces = realSubject.getClass().getInterfaces();
12 Subject proxySubect = DynamicProxy.newProxyInstance(classLoader, interfaces, handler);
13 proxySubect.doSomething("这是一个Dynamic AOP示例!!!");
14 }
15 }
16
17 执行结果:
18 前置通知被执行!
19 do something...这是一个Dynamic AOP示例!!!
20 后置通知被执行!
复制代码
动态代理中invoke的动态调用:

动态代理类DynamicProxy是个纯粹的动态创建代理类通用类。

所以在具体业务中,可以在进一步封装具体的具有业务逻辑意义的DynamicProxy类。

代码如下

具体业务的动态代理:

复制代码
1 package com.yemaozi.proxy.dynamic_aop;
2
3 import java.lang.reflect.InvocationHandler;
4 //具体业务的动态代理。
5 public class SubjectDynamicProxy extends DynamicProxy {
6 public static <T> T newProxyInstance(Subject subject){
7 ClassLoader classLoader = subject.getClass().getClassLoader();
8 Class<?>[] interfaces = subject.getClass().getInterfaces();
9 InvocationHandler handler = new MyInvocationHandler(subject);
10 T t = newProxyInstance(classLoader, interfaces, handler);
11 return t;
12 }
13 }
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式