动态代理:
根据目标对象,在程序运行期自动装配目标对象的代理对象.
优点:可以根据不同的对象,动态装配出对应的代理对象
缺点:采用了反射,导致运行速度会有延迟,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"); } }