发表于: 2018-09-10 20:59:22

1 509


今天完成的事情:(一定要写非常细致的内容,比如说学会了盒子模型,了解了Margin) 

1.代理知识学习

http://www.cnblogs.com/xiaoluo501395377/p/3383130.html

java中的代理技术有很多:jdk,cglib,javassist,ASM等

spring中常用的代理方法

1.jdk自带的jdk  必须有接口   

2.cglib   不需要接口

mybaits中使用了javassist

————————————————————————————————————————

jdk代理【必须要有接口】

1.创建一个接口 写个实现类

public interface HelloWorld {
   public void sayHelloWorld();
}
public class HelloWorldImpl implements  HelloWorld {
   @Override
   public void sayHelloWorld() {
       System.out.println("hello world");
   }
}

2.开始动态代理

在jdk中动态代理逻辑需实现invocationHandler接口

public class JdkProxyExample implements InvocationHandler {
   //真实对象
   private Object target = null;

   /**
    * TODO 建立代理对象和真实对象的代理关系,并范围代理对象
    *
    * newProxyInstance方法中三个参数
    * 1.类加载器
    * 2.代理对象生成后挂在哪个接口下方
    * 3.实现方法逻辑的代理类,this表示当前对象
    *
    * @param target 真实对象
    * @return 代理对象
    * @date 2018/9/9 20:27
    * @author Liu Kai
    **/
   public Object bind(Object target) {
       this.target = target;
       return Proxy.newProxyInstance(target.getClass().getClassLoader(),
               target.getClass().getInterfaces(),
               this);
   }

   /**
    * TODO  代理方法逻辑
    *
    * @param proxy  代理对象
    * @param method 当前调度方法
    * @param args   当前方法参数
    * @return 代理结果返回
    * by Liu Kai 2018/9/10 21:02
    **/
   @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 JdkProxyTest {
   public static void main(String[] args) {
       JdkProxyExample jdk = new JdkProxyExample();
       HelloWorld proxy = (HelloWorld) jdk.bind(new HelloWorldImpl());
       proxy.sayHelloWorld();
   }
}

控制台输出


进入代理逻辑方法

在调度真实对象之前的服务

hello world

在调度真实对象之后的服务

————————————————————————————————————————

2.cglib代理 不需要接口

@Slf4j
public class CglibProxyExample implements MethodInterceptor {
/**
* TODO 生成cglib代理对象
* @param  cls class类
* @return   class类的cglib代理对象
* by Liu Kai 2018/9/10 21:15
**/
public Object getProxy(Class cls){
   //cglib 增强类对象
   Enhancer enhancer  =new Enhancer();
   // 设置增强类类型
   enhancer.setSuperclass(cls);
   // 定义代理逻辑为当前对象,要求当前对象实现methodInterceptor方法
   enhancer.setCallback(this);
   //生成并返回代理对象
   return enhancer.create();
}

   @Override
   public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
     log.error("调度真实对象前");
     Object result = methodProxy.invokeSuper(o,objects);
     log.error("调度真实对象后");
     return result;
   }
}

使用cglib代理对象

写个需要被代理的对象定义一个sayHello方法

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

   }

使用cglib代理这个类,注意 这个类没有实现任何接口

public class CglibProxyTest {
   public static void main(String[] args) {
       CglibProxyExample cpe = new CglibProxyExample();
       ReflectServiceImpl obj = (ReflectServiceImpl) cpe.getProxy(ReflectServiceImpl.class);
       obj.sayHello("张三");
   }
}

控制台输出

21:18:16.711 [main] ERROR com.example.reflectdemo.cglibproxy.CglibProxyExample - 调度真实对象前

hello张三

21:18:16.743 [main] ERROR com.example.reflectdemo.cglibproxy.CglibProxyExample - 调度真实对象后

——————————————————————————————————

我的理解是:

拦截器interceptor运用动态代理方法实现spring中aop的思想

1.定义一个拦截器接口 在其中添加三个方法,设计初期方法逻辑如下

**
* @author Liu Kai
* @Description: TODO 拦截器学习
*方法逻辑:
* proxy 代理对象
* target 真实对象
* method 方法
* args 运行方法的参数
*
* before方法返回boolean值,在真实对象前调用,
*      返回true,反射真实对象
*      返回false,调用around方法
*
* 调用真实对象方法或者around方法后,调用after方法
*
* @date 2018/9/10 17:33
*/
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);
}

2.写个实现类

public class MyInterceptor implements Interceptor {
   @Override
   public boolean before(Object proxy, Object target, Method method, Object[] args) {
       System.out.println("反射方法前逻辑");
       return true;
   }
   @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("反射方法后逻辑");
   }
}

3.在代理中使用拦截器 

public class InterceptorJdkProxy implements InvocationHandler {
   private Object target; // 真实对象
   private String interceptorClass = null; //拦截器权限定名

   public InterceptorJdkProxy(Object target, String interceptorClass) {
       this.target = target;
       this.interceptorClass = interceptorClass;
   }
   /**
    * TODO 绑定委托对象并返回一个【代理占位】
    *
    * @param target 真实对象
    * @return 代理对象【占位】
    * @date 2018/9/10 18:03
    * @author Liu Kai
    **/
   public static Object bind(Object target, String interceptorClass) {
       return Proxy.newProxyInstance(target.getClass().getClassLoader(),
               target.getClass().getInterfaces(),
               new InterceptorJdkProxy(target, interceptorClass));
   }
   @Override
   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;
   }
}

测试

public class InterceptorTest {
   public static void main(String[] args) {
       HelloWorld proxy = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImpl(),
               "com.example.reflectdemo.interceptor.MyInterceptor");
   proxy.sayHelloWorld();
   }
}

结果

反射方法前逻辑

hello world

反射方法后逻辑


通过代理模式实现责任链或者aop的思想

可以定义多个interceptor

HelloWorld porxy1 = (HelloWorld) InterceptorJdkProxy.bind(new HelloWorldImpl()),"Interceptor1")

HelloWorld porxy2 = (HelloWorld) InterceptorJdkProxy.bind(proxy1,"Interceptor2")

HelloWorld porxy3 = (HelloWorld) InterceptorJdkProxy.bind(proxy2,"Interceptor3")

porxy3 .sayHelloWorld();

通过以上方法可以调用多个拦截器,形成责任链模式


明天计划的事情:(一定要写非常细致的内容) 

学习数据结构


遇到的问题:(遇到什么困难,怎么解决的)

java设计除了偶观察者模式外 还有监听者模式

以及redis的订阅发布,

这些是否可以用到消息中心的设计中?

 
收获:(通过今天的学习,学到了什么知识)

了解了一些代理的知识


返回列表 返回列表
评论

    分享到