与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。
但是,JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。
一下是jdk动态代理实例
一:接口
package com.supan.dao; /** * <访问数据库dao层结果> */ public interface DaoInterface { /** * <增加> */ public void insert(String id, String name); /** * <更新> */ public void update(String id, String name); /** * <删除> */ public void delete(String id, String name); /** * <查询> */ public void select(String id, String name); }
二:实现类
package com.supan.dao.imp; import com.supan.dao.DaoInterface; public class PersonDaoImpl implements DaoInterface { @Override public void insert(String id, String name) { System.out.println("********"); System.out.println("增加"); System.out.println(id); System.out.println(name); System.out.println("********"); } @Override public void update(String id, String name) { System.out.println("********"); System.out.println("更新"); System.out.println(id); System.out.println(name); System.out.println("********"); } @Override public void delete(String id, String name) { System.out.println("********"); System.out.println("删除"); System.out.println(id); System.out.println(name); System.out.println("********"); } @Override public void select(String id, String name) { System.out.println("********"); System.out.println("查询"); System.out.println(id); System.out.println(name); System.out.println("********"); } }
三:实现jdk动态代理类的代理工厂
package com.supan.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * <该类是jdk动态代理模式中的核心类> * @author 陈超阳 */ public class DaoProxyObject implements InvocationHandler { /**该属性请用Object类型,通用性强*/ private Object target; /** * <该方法用来返回动态代理对象> * @param target 目标对象 * @return 代理对象 */ public Object bind(Object target) { this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } /** * <动态代理必须要实现的方法,在该方法中可以实现AOP编程> */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; if(method.getName().equals("update") || method.getName().equals("delete") && method.getName().equals("indeset")) { System.out.println("事务开始"); method.invoke(target, args); System.out.println("事务结束"); } else { System.out.println("非事务方法开始调用"); result = method.invoke(target, args); System.out.println("非事务方法调用结束"); } return result; } }
四:测试
package com.supan.test; import com.supan.dao.DaoInterface; import com.supan.dao.imp.PersonDaoImpl; import com.supan.proxy.DaoProxyObject; public class MyDynaProxyTest { public static void main(String[] args) { DaoProxyObject proxy = new DaoProxyObject(); DaoInterface pd = (DaoInterface)proxy.bind(new PersonDaoImpl()); pd.update("33", "chenchaoyang"); pd.select("33", "dddd"); } }
五:输出结果
事务开始
********
更新
33
chenchaoyang
********
事务结束
非事务方法开始调用
********
查询
33
dddd
********
非事务方法调用结束