动态代理:
根据目标对象,在程序运行期自动装配目标对象的代理对象.
优点:可以根据不同的对象,动态装配出对应的代理对象
缺点:采用了反射,导致运行速度会有延迟,JDK的动态代理必须是实现了接口的类(如果不实现接口,可以使用CGLIB)
接口类:UserManager.java
package com.djpowernode.spring; public interface UserManager { public void addUser(String username, String password); }
实现类:UserManagerImpl.java
package com.djpowernode.spring; public class UserManagerImpl implements UserManager { @Override public void addUser(String username, String password) { System.out.println("--------UserManagerImpl.addUser()-----------------"); } }
动态代理类:UserManagerImplProxy.java
package com.djpowernode.spring; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class UserManagerImplProxy implements InvocationHandler { private Object targetObject; public Object createObjectProxy(Object targetObject){ this.targetObject = targetObject; //targetObject.getClass().getClassLoader()取得目标对象的类加载环境 //targetObject.getClass().getInterfaces()取得目标对象的实现的所有接口 //this,代理对象,就是该代理类本身,需要加入新的功能checkScurity() //Proxy.newProxyInstance()根据取得的信息,自动装配出代理对象并返回(在程序运行期自动装配) return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } //重新InvocationHandler中的invoke()方法,会在生成代理对象的时候,自动执行该方法 //根据调用的方法的不同,自动对该方法进行一次封装,执行对应的方法就是在执行invoke()方法 @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.djpowernode.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"); } }