您的位置:首页 > 其它

代理模式

2017-06-27 21:44 50 查看
静态代理:自己定义的代理类;

动态代理:程序在运行时生成。

一、静态代理:

接口:UserManager:对用户的增删改查。

1 package com.dwr.spring.proxy;
2
3 public interface UserManager {
4     public void addUser(String username,String password);
5     public void deleteUser(int userid);
6     public void modifyUser(int userid,String username,String password);
7     public void findUser(int userid);
8 }


实现类:UserManagerImpl:

1 package com.dwr.spring.proxy;
2
3 public class UserManagerImpl implements UserManager {
4     @Override
5     public void addUser(String username, String password) {
6         System.out.println("--------UserManagerImpl.addUser()----------");
7     }
8
9     @Override
10     public void deleteUser(int userid) {
11         System.out.println("--------UserManagerImpl.deleteUser()----------");
12     }
13
14     @Override
15     public void modifyUser(int userid, String username, String password) {
16         System.out.println("--------UserManagerImpl.modifyUser()----------");
17     }
18
19     @Override
20     public void findUser(int userid) {
21         System.out.println("--------UserManagerImpl.findUser()----------");
22     }


客户端类:调用方法;

1 package com.dwr.spring.proxy;
2
3 public class Client {
4
5     public static void main(String[] args){
6         UserManager userManager = new UserManagerImpl();
7         userManager.addUser("Jack","123456");
8     }
9 }


结果:

 1 --------UserManagerImpl.addUser()---------- 

结果正常显示。

在UserManagerImpl中加入安全性检测:

 1
public void checkSecurity(){
2 System.out.println("--------UserManagerImpl.checkSecurity()----------");
3 } 

UserManagerImpl中每个方法都要调用该方法,耦合度提高。使用代理实现类实现该功能:

在代理中:必须要有要控制对象的引用;

将安全检测方法放到代理类中。调用每个方法前进行安全检测,对原有的类的结构并没有破坏,也完成了需求。

UserManagerImplProxy类:

1 package com.dwr.spring.proxy;
2
3 public class UserManagerImplProxy implements UserManager {
4     private UserManager userManager;
5
6     public UserManagerImplProxy(UserManager userManager){
7         this.userManager = userManager;
8     }
9
10     public void checkSecurity(){
11         System.out.println("--------UserManagerImpl.checkSecurity()----------");
12     }
13
14     @Override
15     public void addUser(String username, String password) {
16         checkSecurity();
17         this.userManager.addUser(username,password);
18     }
19
20     @Override
21     public void deleteUser(int userid) {
22         checkSecurity();
23         this.userManager.deleteUser(userid);
24     }
25
26     @Override
27     public void modifyUser(int userid, String username, String password) {
28         checkSecurity();
29         this.userManager.modifyUser(userid,username,password);
30     }
31
32     @Override
33     public void findUser(int userid) {
34         checkSecurity();
35         this.userManager.findUser(userid);
36     }
37 }


客户端测试:

1 package com.dwr.spring.proxy;
2
3 public class Client {
4
5     public static void main(String[] args){
6         //使用静态代理模式实现
7         UserManager userManager = new UserManagerImplProxy(new UserManagerImpl());
8         userManager.addUser("Jack","123456");
9     }
10 }


静态代理模式使我们自己写的,若接口中方法很多,就会很麻烦,这时就需采用AOP来处理!!!

二、动态代理:

既然是动态代理模式就不需要UserManagerImplProxy这个代理类了。

需要声明一个类实现InvocationHandler接口,并定义一个newProxy的方法返回动态代理

1 package com.dwr.spring.proxy;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5 import java.lang.reflect.Proxy;
6
7 public class SecurityHandler implements InvocationHandler {
8     private Object targetObject;
9
10     public Object newProxy(Object targetObject){
11         this.targetObject = targetObject;
12         //返回动态代理
13         return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);
14     }
15
16
17     public void checkSecurity(){
18         System.out.println("--------UserManagerImpl.checkSecurity()----------");
19     }
20
21     @Override
22     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
23         checkSecurity();
24         Object ret = null;
25
26         try {
27             //调用目标对象的真实方法,将返回值保存在ret中
28             ret = method.invoke(this.targetObject, args);
29         } catch (Exception e){
30             e.printStackTrace();
31         }
32         return ret;
33     }
34 }


客户端测试:

1      SecurityHandler securityHandler = new SecurityHandler();
2         UserManager userManager = (UserManager) securityHandler.newProxy(new UserManagerImpl());  //创建代理对象
3         userManager.addUser("Tom","123456");


结果:

 1 --------UserManagerImpl.checkSecurity()----------
2 --------UserManagerImpl.addUser()---------- 

使用动态代理想进行安全检测就进行安全检测;不想检测就不检测,就是这么任性。。。

客户端:

1 package com.dwr.spring.proxy;
2
3 public class Client {
4
5     public static void main(String[] args){
6         SecurityHandler securityHandler = new SecurityHandler();
7         UserManager userManager = (UserManager) securityHandler.newProxy(new UserManagerImpl());//进行了安全检测
8         userManager.addUser("Tom","123456");
9         System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++");
10         UserManager userManager1 = new UserManagerImpl();  //没有进行安全检测
11         userManager1.addUser("Lily","123456");
12     }
13 }


结果:

--------UserManagerImpl.checkSecurity()----------

--------UserManagerImpl.addUser()----------

++++++++++++++++++++++++++++++++++++++++++++++++++

--------UserManagerImpl.addUser()----------

使用CGLib实现:

创建一个类实现MethodInterceptor接口,重写intercept方法:当代理对象的方法被调用时会调用该方法!!

CGlibProxyFactory类:

1 package com.dwr.spring.proxy;
2
3 import org.springframework.cglib.proxy.Enhancer;
4 import org.springframework.cglib.proxy.MethodInterceptor;
5 import org.springframework.cglib.proxy.MethodProxy;
6
7 import java.lang.reflect.Method;
8
9 public class CGlibProxyFactory implements MethodInterceptor {
10
11     private Object targetObject;
12
13     public Object newProxy(Object targetObject){
14         this.targetObject = targetObject;
15         Enhancer enhancer = new Enhancer();
16         enhancer.setSuperclass(this.targetObject.getClass());
17         enhancer.setCallback(this);
18         //返回代理对象
19         return enhancer.create();
20     }
21
22     public void checkSecurity(){
23         System.out.println("--------UserManagerImpl.checkSecurity()----------");
24     }
25
26     /**
27      * @param proxy     带来的对象本身
28      * @param method    被拦截到的方法
29      * @param objects   方法的参数
30      * @param methodProxy   方法的代理对象
31      */
32     @Override
33     public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
34         checkSecurity();
35         Object ret = null;
36
37         try {
38             ret = method.invoke(this.targetObject, objects);
39         } catch (Exception e){
40             e.printStackTrace();
41         }
42         return ret;
43     }
44 }


测试:

1 package com.dwr.spring.proxy;
2
3 public class CGlibProxyTest {
4
5     public static void main(String[] args){
6         CGlibProxyFactory factory = new CGlibProxyFactory();
7         UserManagerImpl userManager = (UserManagerImpl) factory.newProxy(new UserManagerImpl());
8         userManager.addUser("Tom","123456");
9     }
10 }


结果:

--------UserManagerImpl.checkSecurity()----------

--------UserManagerImpl.addUser()----------


 

分类:
JAVA框架

好文要顶
关注我
收藏该文


重重的博客园
关注 - 13
粉丝 - 3

+加关注

0
0

«
上一篇:表达式之谜
»
下一篇:Spring笔记(五)--注解方式实现AOP
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: