Spring笔记(三)--代理模式

静态代理:自己定义的代理类;

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

一、静态代理:

接口: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()----------



原文地址:https://www.cnblogs.com/zhongzhongdebokeyuan/p/5822100.html