Java-动态代理

目标:

学习跟随着书:“Java EE互联网轻量型级框架整合开发,代码也来自这本书。”

1、学习反射技术,掌握反射的基本概念
Java反射技术应用广泛,它能够配置:类的全限定名(绝对路径)、方法和参数,完成对象的初始化,甚至是反射某些方法。这样就能可以大大增强Java的可配置性。
Java的反射内容繁多,包括对象构建、反射方法、注解、参数、接口等。在Java中,反射是通过包java.lang.reflect.*来实现的。
通过反射构建对象

public class ReflectServiceImpl {
	public void sayHello(String name) {
		System.err.println("Hello " + name);
	}
}

通过反射的方法去构建它

	public ReflectServiceImpl getInstance() {
	    ReflectServiceImpl object = null;
	    try {
	        object = 
	            (ReflectServiceImpl) 
	            Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").
	            getConstructor(String.class).newInstance();
	    } catch (ClassNotFoundException | InstantiationException 
	                | IllegalAccessException | NoSuchMethodException 
	                | SecurityException | IllegalArgumentException 
	                | InvocationTargetException ex) {
	            ex.printStackTrace();
	    }
	    return object;
	}

下面这行代码的目的就是给类加载器注册了一个类ReflectServiceImple的全限定名,如何通过newInstance方法初始化了一个类对象。
object = (ReflectServiceImpl2) Class.forName(“com.lean.ssm.chapter2.reflect.ReflectServiceImpl2”).newInstance();

2、动态代理和责任链模式,以及拦截器的概念
动态代理的意义在于生成一个占位(代理对象),来代理真实对象,从而控制真实对象的访问。
假设一个场景,你的公司是一家软件公司,你是一位软件工程师。客户带着需求去公司陷入安不会直接和你谈,而是去找商务谈,此时客户会认为商务代表公司。
客户是通过商务去访问软件工程师的,那么商务(代理对象)的意义在于什么?商务可以进行谈判,项目的各个环节,如价格、进度、时间地点。也可能在开发之前谈崩了,此时商务就会按照规则结束与客户的关系,这些东西都不用软件工程师来处理。因此代理的作用就是,在访问工程师(真实对象)前后处理一些对应的逻辑,上面例子中,商务控制着工程师的访问。
经过上面的例子,了解到了代理模式的概念。我们在访问真实对象前,通过代理对象访问真实对象,这个代理对象与真实对象建立代理关系,所以代理分为2个步骤:
1)代理对象和真实对象建立代理关系
2)实现代理对象的代理逻辑方法
JDK代理:
定义接口

public interface HelloWorld {
	public void sayHelloWorld();
}

实现接口

public class HelloWorldImpl implements HelloWorld {
	@Override
	public void sayHelloWorld() {
		System.out.println("Hello World");
	}
}

这是最坚定的Java接口与实现类的关系,现在可以进行动态代理了。
JDK动态代理中,要实现动态大力逻辑类必须去实现java.lang.reflect.InvocationHandler接口,它里面定义了invoke方法,并提供接口数组用于下挂代理对象
动态代理绑定和代理逻辑实现

public class JdkProxyExample implements InvocationHandler {

	// 真实对象
	private Object target = null;

	/**
	 * 建立代理对象和真实对象的代理关系,并返回代理对象
	 * 
	 * @param target真实对象
	 * @return 代理对象
	 */
	public Object bind(Object target) {
		this.target = target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
	}

	/**
	 * 代理方法逻辑
	 * 
	 * @param proxy
	 *            --代理对象
	 * @param method
	 *            --当前调度方法
	 * @param args
	 *            --当前方法参数
	 * @return 代理结果返回
	 * @throws Throwable
	 *             异常
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("进入代理逻辑方法");
		System.out.println("在调度真实对象之前的服务");
		Object obj = method.invoke(target, args);// 相当于调用sayHelloWorld方法
		System.out.println("在调度真实对象之后的服务");
		return obj;
	}
}

测试动态代理

public class ProxyTest {

	public static void main(String[] args) {
//		testJdkProxy();
		tesCGLIBProxy();
	}

	public static void testJdkProxy() {
		JdkProxyExample jdk = new JdkProxyExample();
		// 绑定关系,因为挂在接口HelloWorld下,所以声明代理对象HelloWorld proxy
		HelloWorld proxy = (HelloWorld) jdk.bind(new HelloWorldImpl());
		// 注意,此时HelloWorld对象已经是一个代理对象,它会进入代理的逻辑方法invoke里
		proxy.sayHelloWorld();
	}
	
	public static void tesCGLIBProxy() {
	    CglibProxyExample cpe = new CglibProxyExample();
	    ReflectServiceImpl obj = (ReflectServiceImpl)cpe.getProxy(ReflectServiceImpl.class);
	    obj.sayHello("张三");
	}

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值