動態代理:
根據目標對象,在程序運行期自動裝配目標對象的代理對象.
優點:可以根據不同的對象,動態裝配出對應的代理對象
缺點:采用了反射,導致運行速度會有延遲,JDK的動態代理必須是實現了接口的類(如果不實現接口,可以使用CGLIB)
接口類:UserManager.java
package com.linuxidc.spring;
public interface UserManager {
public void addUser(String username, String password);
}
實現類:UserManagerImpl.java
package com.linuxidc.spring;
public class UserManagerImpl implements UserManager {
@Override
public void addUser(String username, String password) {
System.out.println("--------UserManagerImpl.addUser()-----------------");
}
}
動態代理類:UserManagerImplProxy.java
package com.bjpowernode.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;
//加載目標的裝載器,目標實現的接口,實現了InvocationHandler的類的對象,會調用對象的invoke方法,並返回代理this(jvm虛擬機中自動裝配)
//已經知道目標的實現的接口,動態創建出目標的一個代理類的對象(this)並返回
//實現了InvocationHandler的類的對象,會調用對象的invoke方法
//根據method拿到對象的當前方法
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object rect = null;
//根據規則,只對add開始的方法代理,類型與Spring中代理實現(Pointcut,Advice)
if(method.getName().startsWith("add123")){
checkScurity();
//method.invoke()取得對象執行的某個方法並執行該方法
rect = method.invoke(targetObject, args);
}
return rect;
}
private void checkScurity(){
System.out.println("------------checkScurity----------");
}
}
測試類:Client.java
package com.linuxidc.spring;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// UserManager userManager = new UserManagerImpl();
UserManagerImplProxy proxy = new UserManagerImplProxy();
UserManager userManager = (UserManager) proxy.createObjectProxy(new UserManagerImpl());
userManager.addUser("張三", "123456");
}
}