popcorn丫

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

代理模式中的角色:

Subject:抽象主题角色,抽象主题类可以是抽象类,也可以是接口,是一个最普通的业务类型定义,无特殊要求。

RealSubject:具体主题角色,也叫被委托角色、被代理角色。是业务逻辑的具体执行者。

Proxy:代理主题角色,也叫委托类、代理类。它把所有抽象主题类定义的方法给具体主题角色实现,并且在具体主题角色处理完毕前后做预处理和善后工作。(最简单的比如打印日志):

 

 

先创建一个被代理对象,该对象必须继承一个接口(否则jdk无法产生动态代理)

 

接口:

1 package com.bxw.service;
2 
3 public interface UserService {
4     public String getName(int id);
5     public Integer getAge(int id);
6 }
UserService.java

 

被代理的对象:

 1 package com.bxw.serviceImpl;
 2 
 3 import com.bxw.service.UserService;
 4 
 5 public class UserServiceImpl implements UserService{
 6 
 7     @Override
 8     public String getName(int id) {
 9         System.out.println("---getNmae---");
10         return "Tom";
11     }
12 
13     @Override
14     public Integer getAge(int id) {
15         System.out.println("---getAge---");
16         return 17;
17     }
18 
19 }
UserServiceImpl.java

 

Handler:

 1 package com.bxw.invocation;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 6 public class MyInvocationHandler implements InvocationHandler {  
 7     //动态代理要有一个被代理的对象
 8     private Object target;  
 9   
10     MyInvocationHandler() {  
11         super();  
12     }  
13   
14     public MyInvocationHandler(Object target) {  
15         super();  
16         this.target = target;  
17     }  
18   
19     @Override  
20     public Object invoke(Object o, Method method, Object[] args) throws Throwable {  
21         if("getName".equals(method.getName())){  
22             System.out.println("++++++before " + method.getName() + "++++++");  
23             Object result = method.invoke(target, args);  
24             System.out.println("++++++after " + method.getName() + "++++++");  
25             return result;  
26         }else{  
27             Object result = method.invoke(target, args);  
28             return result;  
29         }  
30   
31     }
32 }
View Code

 

Test:

 1 package com.bxw.test;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Proxy;
 5 
 6 import com.bxw.invocation.MyInvocationHandler;
 7 import com.bxw.service.UserService;
 8 import com.bxw.serviceImpl.UserServiceImpl;
 9 
10 /**
11  * jdk要实现动态代理那么该类必须实现一个接口
12  * @author Admin
13  *
14  */
15 public class TestDemo {
16      public static void main(String[] args) {  
17             UserService userService = new UserServiceImpl(); //被代理对象 
18             InvocationHandler invocationHandler = new MyInvocationHandler(userService);  
19             //classLoader,interface,产生业务逻辑的Hanfler
20             UserService userServiceProxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(),  
21                     userService.getClass().getInterfaces(), invocationHandler);//产生的代理对象  
22             System.out.println(userServiceProxy.getName(1));  
23             System.out.println(userServiceProxy.getAge(1));  
24      }  
25 }
View Code

 Proxy.newProxyInstance()这个方法有三个参数.第一个是定义代理类型的一个加载者.第二个是要被代理对象的实现的接口列表,第三个是一个对象,这个对象要实现invocationhandler接口的invoke方法来执行你的方法.

 

--------------------------分界线-----------------------------

Cglib代理

 1 package com.bxw.invocation;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 import net.sf.cglib.proxy.Enhancer;
 6 import net.sf.cglib.proxy.MethodInterceptor;
 7 import net.sf.cglib.proxy.MethodProxy;
 8 
 9 public class CglibProxy implements MethodInterceptor {
10     private Object o;
11     
12     public Object getInstance(Object target){
13         this.o = target;
14         Enhancer e = new Enhancer();
15         e.setSuperclass(this.o.getClass());
16         e.setCallback(this);
17         return e.create();
18     }
19     @Override
20     public Object intercept(Object o, Method method    , Object[] args,
21             MethodProxy methodProxy) throws Throwable {
22         System.out.println("-----before"+methodProxy.getSuperName()+"-----");
23         System.out.println(method.getName());
24         //方法、参数
25         Object o1 = methodProxy.invokeSuper(o, args);
26         System.out.println("-----after"+methodProxy.getSuperName()+"-----");
27         return null;
28     }
29 
30 }
CglibProxy.java

getInstance用来获得代理类。

Object o1 = methodProxy.invokeSuper(o, args);注意这里是用invokeSuper方法而不是invoke方法。

 1 package com.bxw.test;
 2 
 3 import com.bxw.invocation.CglibProxy;
 4 import com.bxw.service.UserService;
 5 import com.bxw.serviceImpl.UserServiceImpl;
 6 
 7 public class TestDemo2 {
 8     public static void main(String[] args) {
 9         CglibProxy cl = new CglibProxy();
10         UserService u = (UserService) cl.getInstance(new UserServiceImpl());
11         u.getAge(1);
12         u.getAge(1);
13     }
14 }
Test

 

posted on 2017-05-25 23:25  popcorn丫  阅读(116)  评论(0编辑  收藏  举报