Java动态代理--反思1

Java动态代理–反思1

问题的产生

今天早晨起来 闲来无事 就顺便看了下 之前的动态代理的 代码;发现生成代理对象的方法Object java.lang.reflect.Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException 其第二个参数是 一个CLass数组对象;我就想 原来放到是代理对象(经测试是 实现对象UserServiceImpl,非实现对象的接口UserService)实现的实现接口;能不能通过改变这个参数生成不同方法来 实现屏蔽 代理对象的一些方法;于是就产生了 接下来的修改及测试;
那么接下来上修改后的代码:

修改的面目全非的代码

接口部分 根据上述思路 多写了一个接口
接口一
package proxy.service;

/**
 * 额外接口 用于实验 是否能通过往 newProxyInstance 传入 第二个接口数组参数 不同 来屏蔽一些代理对象的方法
 * @author admin
 *
 */
public interface AdditionalInterface {

	void dance();
	void sing();
}

接口二
package proxy.service;

/**
 * 被代理对象接口
 * @author admin
 *
 */
public interface UserService {
	void eat();
	void speak();
}
实现部分
package proxy.service.impl;

import proxy.service.AdditionalInterface;
import proxy.service.UserService;

public class UserServiceImpl implements UserService,AdditionalInterface {

	@Override
	public void eat() {
		System.out.println("吃饭中。。。");
	}

	@Override
	public void speak() {
		System.out.println("说话中。。。");
	}

	@Override
	public void dance() {
		System.out.println("跳舞中。。。");
	}
	@Override
	public void sing() {
		System.out.println("唱歌中。。。");
	}

}

生成代理对象方法所在的类
package proxy.service;

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

/**
 * 切面类 合并 具有生成代理对象 的类
 * @author admin
 *
 */
public class MyRepect implements InvocationHandler{
	
	private Object us ;

	public MyRepect(Object us) {
		super();
		this.us = us;
	}

	public void before() {
		System.out.println("前置方法");
	}
	
	public void after() {
		System.out.println("后置方法");
	}

	//获取代理类 之所以要类类加载器参数  是 代理类 动态生成的  并没有class文件
	public Object getUserService() {
		return Proxy.newProxyInstance(us.getClass().getClassLoader(), new Class[] { UserService.class,AdditionalInterface.class }, this);
	}

	//交织 业务类 和 切面类 
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		before();
		Object ret = method.invoke(us, args);
		after();
		return ret;
	}
}

测试代码
package proxy.test;

import proxy.service.AdditionalInterface;
import proxy.service.MyRepect;
import proxy.service.UserService;
import proxy.service.impl.UserServiceImpl;

public class MainTest {

	public static void main(String[] args) {
		
		//获取被代理对象
		Object us = new UserServiceImpl();
	    MyRepect myRepect = new MyRepect(us); 
	    //执行 额外接口的方法
	    AdditionalInterface additionalInterface = (AdditionalInterface) myRepect.getUserService(); 
	    additionalInterface.sing();
	    System.out.println("---------------------------华丽的分割线---------------------------");
	    //执行原始接口的方法
	    UserService userService = (UserService) myRepect.getUserService(); 
	    userService.eat();
	}
}

执行结果

在这里插入图片描述

思考及总结

1、通过上面的代码修改 可以在测试的地方强转成不同的 接口 然后去调用相应的方;感觉就和没有代理是一样的;当然不考虑公共业务的添加; 也从另外一个方面看出 方法newProxyInstance 第二个参数的作用 如果传入的参数 没有对应的接口 那么生成的代理对象是没有这个接口下面的方法的;也说明了 如果代理方法没有接口的话 无法使用这个代理类生成的工具;
2、感觉如果说按照我上面的思想 其实 MyRepect 应该根据 代理类 的不同方法 添加不同公共扩展 然后写成一个版本的 MyRepect; 但是后来我又想到一个问题 如果说 代理类所有方法要实现的公共扩展怎么办;难道还要在不同版本的MyRepect里面添加 代码吗? 这样不就降低了代码的复用率 ;感觉 实现类 实现的接口应该 是 一个继承了 上面例子 的两个接口 ; 如果 要给代理类所有方法 增加扩展就用 这个接口 ;如果分开的话 就按照上面的方式来; 下面我画了一个图 不知道能不能阐述清楚我的想法
在这里插入图片描述
最后 看着改后代码 ;感觉 还是有种不和谐的感觉;但又说不来;如果需要讨论可以下方留下评论,欢迎大家给予批评指正;Thanks♪(・ω・)ノ

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值