60s讓你學會動態代理原理,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 stubcheckSecurity();userManager.addUser(username, password);}public void delUser(int userId) {// TODO Auto-generated method stubcheckSecurity();userManager.delUser(userId);}public String findUserById(int userId) {// TODO Auto-generated method stubcheckSecurity();return userManager.findUserById(userId);}public void modifyUser(int userId, String username, String password) {// TODO Auto-generated method stubcheckSecurity();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 stubUserManagerImpl 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 stubcheckSecurity();//調用目標方法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容器的結合讓我們對系統提供服務更加的方便了這樣我們也就實現了開閉原則。這樣也就能實現了對象想要的時候就有不用的時候就撤出全心全意為開發人員服務。
怎才可以讓一個小白學會做bilibili的空間CSS 傳授 讓我知道原理就行
CSS我不太會。但div+css入門是互連網裡最簡單的。
div是HTML語言裡一個沒有意義的標籤,正因為其沒有意義,所以可以隨意給他定義CSS,
CSS全稱是層疊樣式表什麼的,也就是說在CSS裡給div標籤定義:長度、寬度、顏色、字型、位置等等各種樣式。
也就是說,你看到的頁面,其實就是N多個div標籤構成的,只不過給他CSS了,所以才有大的有小的。
如果你完全不懂的話推薦你看下 LAMP兄弟連 的基礎視頻,有講CSS的。
傳送門:www.lampbrother.net/phptrain/video.php
然後想專研CSS的話還是需要各種練習各種項目。
讓紙杯裡的水瞬間消失的那個魔術是什原理?(本人學會後保證不透漏魔術秘密)
這種魔術的原理主幹——使水消失
關鍵是如何消失,方法如下:
1.在被子裡放一塊品質好的海綿(不一定要海綿,能吸水的就行)將水倒入後,要等一段時間,這個時間內魔術師一般會念一些咒語或耍一些手法,這些都是次要的,關鍵是讓海綿吸水。
2.這個杯子是道具,有夾層(不過可能性很小)
魔術不光是要破解其秘密,更重要的是從中得到快樂