与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由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
********
非事务方法调用结束