zoukankan      html  css  js  c++  java
  • 菜鸟学习Spring——60s让你学会动态代理原理

    一、为什么要使用动态代理
            当一个对象或多个对象实现了N中方法的时候,由于业务需求需要把这个对象和多个对象的N个方法加入一个共同的方法,比如把所有对象的所有方法加入事务这个时候有三种方法:
            方法一:一个一个对象一个一个方法去加,很显然这个方法是一个比较笨的方法。
            方法二:加一个静态代理对象将这个静态代理对象实现要加事务对象的接口。然后在静态代理对象里面每个方法里面加上事务。
            方法三:使用动态代理对象,进行动态的加载事务。
            使用动态代理是为了让对象实现了开闭原则,对扩展开放,而对修改关闭。Spring的AOP其实就是用了动态代理+IoC容器实现的
    二、代码实现。

            UserManger.java接口

    	package com.tgb.spring;
    	
    	public interface UserManager {
    		
    		public void addUser(String username,String password);
    		
    		public void delUser(int userId);
    		
    		public String findUserById(int userId);
    		
    		public void modifyUser(int userId,String username,String password);
    		
    	}
    


    方法一 常规的做法:

              UserMangerImpl.Java

    	package com.tgb.spring;
    	
    	public class UserManagerImpl implements UserManager {
    	
    		public void addUser(String username, String password) {
    			checkSecurity();
    				System.out.println("UserManager.addUser");
    	
    		}
    	
    		public void delUser(int userId) {
    			checkSecurity();
    			System.out.println("UserManager.delUser");
    	
    		}
    	
    		public String findUserById(int userId) {
    			checkSecurity();
    			System.out.println("UserManager.findUserById");
    		return	"张三";
    		}
    	
    		public void modifyUser(int userId, String username, String password) {
    			checkSecurity();
    			System.out.println("UserManager.modifyUser");
    	
    		}
    		
    		private void checkSecurity(){
    			System.out.println("checkSecurity");
    	
    		}
    	}
    


    Client.java

    	package com.tgb.spring;
    	
    	public class Client {
    	
    		/**
    		 * @param args
    		 */
    		public static void main(String[] args) {
    			UserManager userManager=new UserManagerImpl();
    			userManager.addUser("11", "1231");
    		}
    	
    	}
    


    方法二 静态代理:

           UserManagerImpl.java

    	package com.tgb.spring;
    	
    	public class UserManagerImpl implements UserManager {
    	
    		public void addUser(String username, String password) {
    			//checkSecurity();
    				System.out.println("UserManager.addUser");
    	
    		}
    	
    		public void delUser(int userId) {
    			//checkSecurity();
    			System.out.println("UserManager.delUser");
    	
    		}
    	
    		public String findUserById(int userId) {
    			//checkSecurity();
    			System.out.println("UserManager.findUserById");
    		return	"张三";
    		}
    	
    		public void modifyUser(int userId, String username, String password) {
    			//checkSecurity();
    			System.out.println("UserManager.modifyUser");
    	
    		}
    		
    	//	private void checkSecurity(){
    	//		System.out.println("checkSecurity");
    	//
    	//	}
    	
    	}
    	
    


            UserManagerImplProxy.java

    	package com.tgb.spring;
    	
    	public class UserManagerImplProxy implements UserManager {
    	
    		private UserManager userManager;
    		
    		public UserManagerImplProxy(UserManager userManager){
    			this.userManager=userManager;
    		}
    		
    		public void addUser(String username, String password) {
    			// TODO Auto-generated method stub
    			checkSecurity();
    			userManager.addUser(username, password);
    		}
    	
    		public void delUser(int userId) {
    			// TODO Auto-generated method stub
    			checkSecurity();
    			userManager.delUser(userId);
    		}
    	
    		public String findUserById(int userId) {
    			// TODO Auto-generated method stub
    			checkSecurity();
    			
    			return userManager.findUserById(userId);
    		}
    	
    		public void modifyUser(int userId, String username, String password) {
    			// TODO Auto-generated method stub
    			checkSecurity();
    			userManager.modifyUser(userId, username, password);
    	
    		}
    	
    				private void checkSecurity(){
    						System.out.println("checkSecurity");
    			
    			}
    	}
    	
    


    Client.java

    	package com.tgb.spring;
    	
    	public class Client {
    	
    		/**
    		 * @param args
    		 */
    		public static void main(String[] args) {
    			// TODO Auto-generated method stub
    			UserManagerImpl uesrMangerImpl=new UserManagerImpl();
    			UserManager userManager=new UserManagerImplProxy(uesrMangerImpl);
    			
    			userManager.addUser("11", "1231");
    		}
    	
    	}
    


    方法三:动态代理

            UserManagerImpl.java与方法二的UserManagerImpl.java一样把UserManagerImplProxy.java删除

            新添一个类:

            SecurityHandler.java

    	package com.tgb.spring;
    	
    	import java.lang.reflect.InvocationHandler;
    	import java.lang.reflect.Method;
    	import java.lang.reflect.Proxy;
    	
    	public class SecurityHandler implements InvocationHandler {
    	
    		private Object targetObject;
    		
    		public Object createProxyInstance(Object targetObject){
    			this.targetObject=targetObject;
    			return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), 
    									targetObject.getClass().getInterfaces(), 
    									this);
    		}
    		
    		public Object invoke(Object proxy, Method method, Object[] args)
    				throws Throwable {
    			// TODO Auto-generated method stub
    			checkSecurity();
    			//调用目标方法
    			Object ret=method.invoke(targetObject, args);
    			return ret;
    		}
    	
    		
    		private void checkSecurity(){
    			System.out.println("checkSecurity");
    	
    		}
    	
    	
    	}
    


             Client.java

    	package com.tgb.spring;
    	
    	
    	
    	public class Client {
    	
    		public static void main(String[] args) {
    			SecurityHandler handler=new SecurityHandler();
    			UserManager userManager=(UserManager)handler.createProxyInstance(new UserManagerImpl());
    			userManager.addUser("zha", "123");
    		}
    	}
    


           三种方法的效果是一样的如图:


    三、总结。

            动态代理的利用给我们编码带来了很大的便利,解决了动态为对象提供服务的方案。动态代理+IoC容器的结合让我们对系统提供服务更加的方便了这样我们也就实现了开闭原则。这样也就能实现了对象想要的时候就有不用的时候就撤出全心全意为开发者服务。

  • 相关阅读:
    Vue 中常见性能优化
    简单模板引擎实现
    函数柯理化
    url 解析
    快排
    防抖节流实现
    call、apply、bind 实现
    深克隆
    数组去重
    eventEmitter 简单实现
  • 原文地址:https://www.cnblogs.com/iplus/p/4490370.html
Copyright © 2011-2022 走看看