疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

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()----------