java代理

代理

概念

         代理模式是对象的结构型模式,代码模式给某一个对象提供代理,并由代理对象控制原对象(目标对象,被代理对象)的引用。简单点说,就是经过一个工厂生成一个类的代理对象,当客户端使用的时候不直接使用目标对象,而是直接使用代理对象。代理对象至关于中介.java

1        Jdk静态代理

1.1     概念

1.1.1     代理类和目标类实现相同的接口

1.1.2     代理类持有目标类的     的引用

1.2      实例

1.2.1     建立接口

public interface UserService {  web

    public void addUser(String userId,String userName);  spring

}  ide

1.2.2     建立实现类

public class UserServiceImpl implements UserService {测试

    @Overridethis

    public void addUser(String userId, String userName) {spa

       System.out.println("UserServiceImpl addUser userId->>"+userId);.net

    }代理

}对象

1.2.3     建立代理类

(代理类持有被代理类的引用)

public class UserServiceImplProxy implements UserService {

    private UserService userService;

    public UserServiceImplProxy(UserService userService){

       this.userService = userService;

    }

    @Override

    public void addUser(String userId, String userName) {

       try {

           System.out.println("开始执行:addUser");

           userService.addUser(userId, userName);

           System.out.println("addUser执行成功。");

       } catch (Exception e) {

           System.out.println("addUser执行失败。");

       }

    }

         }

1.2.4     建立测试类

public class Client {

         public static void main(String[] args) {

          UserService userService = new UserServiceImplProxy(new UserServiceImpl());

          userService.addUser("001", "centre");

         }

}

1.2.5     缺点

须要为每个目标类建立一个代理类,须要创建大量的代理类,耦合度高.违背了重复代码只写一次的原则.

 

 

2        Jdk动态代理

2.1     概念

Jdk的动态要求目标对象必须实现接口,由于它建立代理对象的时候是根据接口建立的。若是不实现接口,jdk没法给目标对象建立代理对象。被代理对象能够能够实现多个接口,建立代理时指定建立某个接口的代理对象就能够调用该接口定义的方法了   

2.1.1     被代理对象必须实现接口,能够实现多个接口

2.1.2     代理对象由代理工厂生成

2.2     实例

2.2.1   建立接口Service接口和UserService接口(上面的接口)

public interface Service {

      public void sayHello(String name);

}

 

2.2.2     建立目标对象

public class UserServiceImpl implements UserService ,Service{

         @Override

         public void addUser(String userId, String userName) {

                   System.out.println("UserServiceImpl addUser userId->>"+userId);

         }

@Override

         public void sayHello(String name) {

                   System.out.println("你好:"+name);

         }

              }

2.2.3     建立生成代理对象的类

 

public class LogHandler implements InvocationHandler {

         private Object targertObject;

         public Object newInstance(Object targertObject){

                   this.targertObject = targertObject;

                   Class targertClass = targertObject.getClass();

                return  Proxy.newProxyInstance(targertClass.getClassLoader(),

targertClass.getInterfaces(),this);

         }

  @Override

         public Object invoke(Object proxy, Method method, Object[] args)

                            throws Throwable {

                   System.out.println("调用方法"+method.getName());

                   Object ret = null;

                   try {

                            ret = method.invoke(targertObject, args);

                            System.out.print("成功调用方法:"+method.getName()+";参数为:");

                            for (int i = 0; i < args.length; i++) {

                                     System.out.println(args[i]);

                            }

                   } catch (Exception e) {

                            e.printStackTrace();

                            System.out.print("调用方法:"+method.getName()+"失败;参数为:");

                            for (int i = 0; i < args.length; i++) {

                                     System.out.print(args[i]);

                            }

                   }

                   return ret;

         }

}

2.2.4     建立测试类

public class Client {

         public static void main(String[] args) {

                   Service Service = (Service)new LogHandler().newInstance(new UserServiceImpl());

                   UserService userService = (UserService)new LogHandler().newInstance(new UserServiceImpl());

                   userService.addUser("001", "centre");

                   Service.sayHello("centre");

         }

}

2.2.5     缺点

jdk给目标类提供动态要求目标类必须实现接口,当一个目标类不实现接口时,jdk是没法为其提供动态代理的

3        Jdk动态代理

3.1     CGLIB动态代理

spring在给某个类提供动态代理时会自动在jdk动态代理和cglib动态代理中动态的选择。使用cglib为目标类提供动态代理:须要导入cglib.jar和asm.jar

若是出现asm中的类没法找到的异常,在java工程中是真的缺乏asm.jar,而在web工程中极可能是asm.jar和spring提供的org.springframework.asm-3.0.4.RELEASE.jar包冲突。

3.1.1    CGLIB动态代理首先编写一个目标类:UserServiceImpl.java(上面的类)

3.1.2    而后为其建立一个代理工厂,用于生成目标类的代理对象:CglibProxy.java

若是一个类继承了某个类,在子类中没有一个方法,用cglib生成该子类的动态代理类中将没有一个方法。

3.1.3     编写CGLIB代理类

public class CglibProxy implements MethodInterceptor{

 

         @Override

         public Object intercept(Object obj, Method method, Object[] args,

                            MethodProxy proxy) throws Throwable {

        System.out.println("调用的方法是:" + method.getName());

        Object ret = null;

        try {

            ret = proxy.invokeSuper(obj, args);

                            System.out.print("成功调用方法:"+method.getName()+";参数为:");

                            for (int i = 0; i < args.length; i++) {

                                     System.out.print(args[i]);

                            }

                   } catch (Exception e) {

                            e.printStackTrace();

                            System.out.print("调用方法:"+method.getName()+"失败;参数为:");

                            for (int i = 0; i < args.length; i++) {

                                     System.out.print(args[i]);

                            }

                   }

                   return ret;

         }

}

3.1.4     编写测试类

public class CglibClient {

         public static void main(String[] args) {

                   cglibUse1();

         }

         public static void cglibUse1(){

                   Enhancer enhancer = new Enhancer();

 

                   // 设置被代理的类(目标类)

                   enhancer.setSuperclass(UserServiceImpl.class);

                   //使用回调

                   enhancer.setCallback(new CglibProxy());

 

                   // 创造 代理 (动态扩展了UserServiceImpl类)

                   UserServiceImpl my = (UserServiceImpl) enhancer.create();

 

                   //my.addUser("001", "centre");

                   int ret = my.addOperter(15, 22);

                   System.out.println("返回的结果是:"+ret);

         }

}

4         jdk动态和cglib动态代理比较

Jdk动态代理要求被代理的类要实现接口,而cglib不须要,cglib能根据内存中为其建立子类(代理对象)

5        我的理解

Jdk静态代理能够理解为中介(代理类)知道一切,全部的事情由中介来处理,其余的类完成本身的功能就行了.

jdk动态代理以接口做为媒介,利用反射创建起代理类和被代理类的关系.

CGLib的具体还有点没有理解,但愿能够有人补充.

 

摘自: http://blog.csdn.net/centre10/article/details/6847828

相关文章
相关标签/搜索