动态代理模式:
1、产生的代理对象和目标对象实现了共同的接口
jdk动态代理
2、代理对象是目标对象的子类
hibernate: Person person = session.load(Person.class,1L); javassisit
spring:cglib动态代理
jdk的动态代理:
1、因为是用jdk的API做到的
2、代理对象是动态产生的
cglib产生的代理类是目标类的子类
注意事项:
1、拦截器中invoke方法体的内容就是代理对象方法体的内容
2、当客户端执行代理对象.方法时,进入到了拦截器的invoke方法体
3、拦截器中invoke方法的method参数是在调用的时候赋值的
例子
存入数据库的person
public class Person implements Serializable{
private Long pid;
private String pname;
private String psex;
set,get方法}
接口PersonDao
public interface PersonDao {
public String savePerson(Person person);}
hibernate工具类
public class HibernateUtils {
public static SessionFactory sessionFactory;
static{
Configuration config = new Configuration();
config.configure("/proxy/cn/itcast/jdkproxy/hibernate/hibernate.cfg.xml");
sessionFactory = config.buildSessionFactory();}}
实现类PersonDaoImpl
public class PersonDaoImpl extends HibernateUtils implements PersonDao{
public String savePerson(Person person) {
sessionFactory.getCurrentSession().save(person);
return "save a person";
}
事务切面Transaction
public class MyTransaction extends HibernateUtils{
private Transaction tran;
public void beginTran(){
this.tran = sessionFactory.getCurrentSession().beginTransaction();}
public void commit(){
this.tran.commit();}}
hibernate映射文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<!-- 用来描述一个持久化类 name 类全名 table 表名,默认值和类名一样 catalog 数据库名称,一般不写 -->
<class name="proxy.cn.itcast.jdkproxy.hibernate.Person">
<!-- 标示属性 和数据库中的主键对应 name 属性的名称 column 列的名称 -->
<id name="pid" column="pid" length="200" type="java.lang.Long">
<!-- 主键的产生器 就该告诉hibernate容器用什么样的方式产生主键 -->
<generator class="increment"></generator></id>
<!-- 描述一般属性 -->
<property name="pname" column="pname" length="20" type="string"></property>
<property name="psex" column="psex" length="10" type="java.lang.String"></property>
</class>
</hibernate-mapping>
拦截器
public class PersonDaoInterceptor implements InvocationHandler{
private Object obj;
private MyTransaction myTran;
public PersonDaoInterceptor(Object obj,MyTransaction myTran){
this.obj = obj;
this.myTran = myTran;}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
this.myTran.beginTran();
Object obj = method.invoke(this.obj, args);
this.myTran.commit();
return obj;}}
测试类
public class ProxyTest {
@Test
public void test1(){
Object obj = new PersonDaoImpl();
MyTransaction myTran = new MyTransaction();
PersonDaoInterceptor interceptor= new PersonDaoInterceptor(obj, myTran);
PersonDao pdao = (PersonDao) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), interceptor);
Person person = new Person();
person.setPname("pengya");
person.setPsex("female");
String s = pdao.savePerson(person);
System.out.println(s);
}
}
cglib产生的代理类是目标类的子类
1.拦截器实现net.sf.cglib.proxy.MethodInterceptor;
2.代码加强机制-生成代理对象
public Object createProxy(){
Enhancer enhancer = new Enhancer();
enhancer.setCallback((Callback) this);
enhancer.setSuperclass(this.target.getClass());
return enhancer.create();
}
3.覆盖intercept方法
@Override
public Object intercept(Object obj, Method method, Object[] obj2,
MethodProxy methodproxy) throws Throwable {
for(Interceptor interceptor : interceptors){
interceptor.interceptor();
}
method.invoke(this.target, obj2);
return null;
}
4.测试类
SalaryInterceptor salaryinterceptor = new SalaryInterceptor(target, list);
SalaryManager sm = (SalaryManagerImpl) salaryinterceptor.createProxy();
sm.showSalary();