软件编程
位置:首页>> 软件编程>> java编程>> Java * 之 * 的应用

Java * 之 * 的应用

作者:Haozz_1994  发布时间:2022-11-24 11:18:55 

标签:java, , , ,

由于 * 一般都比较难理解,程序设计者会设计一个 * 接口供开发者使用,开发者只要知道 * 接口的方法、含义和作用即可,无须知道 * 是怎么实现的。用JDK * 来实现一个 * 的逻辑,为此先定义 * 接口Interceptor,如下所示:


/**
* @Auther: haozz
* @Date: 2018/5/27 22:15
* @Description: * 接口
**/
public interface Interceptor {
 boolean before(Object proxy, Object target, Method method,Object[] args);
 void around(Object proxy,Object target,Method method,Object[] args);
 void after(Object proxy,Object target,Method method,Object[] args);
}

这里定义了3个方法,before、around、after方法,分别给予这些方法如下逻辑定义:

  1. 3个方法的参数为:proxy代理对象、target真实对象、method方法、args运行方法参数;

  2. before方法返回boolean值,它在真实对象前调用。当返回为true时,则反射真实对象的方法;当返回为false时,则调用around方法;

  3. 在before方法返回为false的情况下,调用around方法

  4. 在反射真实对象方法或者around方法执行之后,调用after方法

实现这个Interceptor的实现类——MyInterceptor,如下:


/**
* @Auther: haozz
* @Date: 2018/5/27 22:48
* @Description:MyInterceptor
**/
public class MyInterceptor implements Interceptor{
 @Override
 public boolean before(Object proxy, Object target, Method method, Object[] args) {
   System.out.println("反射方法前逻辑");
   return false;//不反射被代理对象原有方法
 }
 @Override
 public void around(Object proxy, Object target, Method method, Object[] args) {
   System.out.println("取代了被代理对象的方法");
 }
 @Override
 public void after(Object proxy, Object target, Method method, Object[] args) {
   System.out.println("反射方法后逻辑");
 }
}

它实现了所有Interceptor接口的方法,使用JDK * ,就可以去实现这些方法在适当时的调用逻辑了。以上一篇(Java设计模式之 * )中的接口和实现类为例,在JDK * 中使用 * ,如下所示:


/**
* @Auther: haozz
* @Date: 2018/5/27 22:30
* @Description:
**/
public class InterceptorJdkProxy implements InvocationHandler {
 private Object target;//真实对象
 private String interceptorClass = null;// * 全限定名
 public InterceptorJdkProxy(Object target,String interceptorClass){
   this.target = target;
   this.interceptorClass = interceptorClass;
 }
 public static Object bind(Object target,String interceptorClass){
   //取得代理对象
   return Proxy.newProxyInstance(target.getClass().getClassLoader(),
       target.getClass().getInterfaces(),
       new InterceptorJdkProxy(target,interceptorClass));
 }
 @Override
 /**
  * Description:通过代理对象调用方法,首先进入这个方法
  * @auther: haozz
  * @param: proxy 代理对象
  * @param: method 被调用方法
  * @param: args 方法的参数
  * @return: java.lang.Object
  * @date: 2018/5/27 23:00
  **/
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   if(interceptorClass == null){
     //没有设置 * 则直接反射原有方法
     return method.invoke(target,args);
   }
   Object result = null;
   //通过反射生成 *
   Interceptor interceptor = (Interceptor) Class.forName(interceptorClass).newInstance();
   //调用前置方法
   if(interceptor.before(proxy,target,method,args)){
     //反射原有对象方法
     result = method.invoke(target,args);
   }else{//返回false执行around方法
     interceptor.around(proxy,target,method,args);
   }
   //调用后置方法
   interceptor.after(proxy,target,method,args);
   return result;
 }
}

这里有两个属性,一个是target,它是真实对象;另一个是字符串interceptorClass,它是一个 * 的全限定名。解释以下这段代码的执行步骤:

        第1步,在bind方法中用JDK * 绑定了一个对象,然后返回代理对象;

        第2步,如果没有设置 * ,则直接反射真实对象的方法,然后结束,否则进行第3步;

        第3步,通过反射生成 * ,并准备使用它;

        第4步,调用 * 的before方法,如果返回为true,反射原来的方法;否则运行 * 的around方法;

        第5步,调用 * 的after方法;

        第6步,返回结果。

  • 开发者只要知道 * 的作用就可以编写 * 了,编写完后可以设置 * ,这样就完成了任务,所以对于开发者而言相对简单了

  • 设计者可能是精通Java的开发人员,他来完成 * 的逻辑

  • 设计者只会把 * 接口暴露给开发者使用,让 * 的逻辑在开发者的视野中“消失”

* 可以进一步简化 * 的使用方法,使程序变得更简单,用如下的测试类测试一下:


public class Mytest {
 public static void main(String []args){
   HelloWorld proxy1 = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImpl(),"com.csdn.blog.interceptor.MyInterceptor");
   proxy1.sayHelloWorld();
 }
}

运行这段代码,得到以下结果:

反射方法前逻辑
取代了被代理对象的方法
反射方法后逻辑

显然, * 已经生效。

来源:https://blog.csdn.net/hz_940611/article/details/80473696

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com