一、基于接口的动态代理

1、被代理的类实现的接口

package cn.itcast.proxy;/*** 经纪公司的签约演员的规范* @author zhy**/
public interface IActor {public void basicAct(float money);public void dangerAct(float money);
}

2、被代理的类

package cn.itcast.proxy;/*** 演员类动作类
* @Description: TODO
* @author wingzhe  */
public class Actor implements IActor {public void basicAct(float money){System.out.println("拿到"+money+"元,开始表演");}public void dangerAct(float money) {System.out.println("拿到"+money+"元,开始进行危险动作");}
}

3、实现代理功能

package cn.itcast.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class Client {/***  模拟一个剧组* @param args*/public static void main(String[] args) {final Actor actor = new Actor();/*** Proxy:*    用于创建代理对象的类。是JDK官方提供的*  使用newProxyInstance方法创建。*  创建的要求:被代理对象必须最少实现一个接口* newProxyInstance方法的参数:*   ClassLoader:和被代理对象使用相同的类加载器。*  Class[]:和被代理对象具有相同的行为(实现相同的接口)*  InvocationHandler:一般情况下是一个匿名内部类,提供invoke方法的实现。*                 在invoke方法中写的,就是增强部分的代码。*               简单的说,这个参数它的含义就是:如何代理。*                此接口的实现类(匿名内部类):谁用谁写。*                  策略模式:*                   数据已经有了*                     目的明确*                   如何达成目标:谁用谁写。写出来的就是策略。* * 动态代理的作用:*        在不修改源码的基础上,运行期间对方法进行增强*/IActor proxyActor = (IActor) Proxy.newProxyInstance(actor.getClass().getClassLoader(), actor.getClass().getInterfaces(), new InvocationHandler() {/*** 执行被代理对象的任何方法,都会经过该方法。此方法有拦截功能* 参数详解:*  Object proxy:代理对象的引用*    Method method:当前执行的方法对象*  Object[] args:执行方法时所需的参数* 返回值:*  Object:当前执行方法的返回值*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object rtValue = null;//1.取出moneyFloat money = (Float)args[0];//2.判断如果基本的表演,没有2000块钱,不演if("basicAct".equals(method.getName())){if(money > 2000){rtValue = method.invoke(actor, money/2);}}//3.判断如果是危险表演,没有20000块钱,不演if("dangerAct".equals(method.getName())){if(money > 20000){rtValue = method.invoke(actor, money/2);}}return rtValue;}});//     actor.basicAct(500);
//      actor.dangerAct(1000);proxyActor.basicAct(5000);proxyActor.dangerAct(100000);}}

二、基于子类的动态代理

1、创建项目,导入第三方jar包

2、创建被代理类

package cn.itcast.cglib;
/*** 一个演员* @author zhy**/
public class Actor {public void basicAct(float money){System.out.println("拿到钱,开始基本的表演:"+money);}public void dangerAct(float money){System.out.println("拿到钱,开始危险的表演:"+money);}
}

3、创建执行动作的代理类

package cn.itcast.cglib;import java.lang.reflect.Method;import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;public class Client {public static void main(String[] args) {final Actor actor = new Actor();/*** Enhancer:*         它是cglib提供的一个类,用于创建代理对象的。*        create方法是创建代理对象的方法。*        使用要求:被代理对象不能是最终类。(类不能被final修饰)* 方法的参数:*      Class:被代理对象的字节码*    Callback:如何代理。(也是策略模式)*/Actor cglibActor = (Actor)Enhancer.create(actor.getClass(), new MethodInterceptor() {/*** 执行被代理对象的任何方法,都会经过该方法。此方法也有拦截的功能。* 和InvocationHandler中的invoke方法作用是一样的* 方法的参数:*     前面三个参数和invoke方法中的含义一模一样。*  MethodProxy methodProxy:当前执行方法的代理对象。* * 方法的返回值:*  当前执行方法的返回值*/@Overridepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {Object rtValue = null;//1.取出moneyFloat money = (Float)args[0];//2.判断如果基本的表演,没有2000块钱,不演if("basicAct".equals(method.getName())){if(money > 2000){rtValue = method.invoke(actor, money/3);}}//3.判断如果是危险表演,没有20000块钱,不演if("dangerAct".equals(method.getName())){if(money > 20000){rtValue = method.invoke(actor, money/3);}}return rtValue;}});cglibActor.basicAct(8000);cglibActor.dangerAct(60000);}}

三、动态代理实现事务控制

1、编写javaBean

package cn.itcast.domain;import java.io.Serializable;
/*** 客户的实体类* @author zhy**/
public class Customer implements Serializable {private Long custId;private String custName;private String custSource;private String custIndustry;private String custLevel;private String custAddress;private String custPhone;public Long getCustId() {return custId;}public void setCustId(Long custId) {this.custId = custId;}public String getCustName() {return custName;}public void setCustName(String custName) {this.custName = custName;}public String getCustSource() {return custSource;}public void setCustSource(String custSource) {this.custSource = custSource;}public String getCustIndustry() {return custIndustry;}public void setCustIndustry(String custIndustry) {this.custIndustry = custIndustry;}public String getCustLevel() {return custLevel;}public void setCustLevel(String custLevel) {this.custLevel = custLevel;}public String getCustAddress() {return custAddress;}public void setCustAddress(String custAddress) {this.custAddress = custAddress;}public String getCustPhone() {return custPhone;}public void setCustPhone(String custPhone) {this.custPhone = custPhone;}}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.domain"><class name="Customer" table="cst_customer"><id name="custId" column="cust_id"><generator class="native"></generator></id><property name="custName" column="cust_name"></property><property name="custIndustry" column="cust_industry"></property><property name="custSource" column="cust_source"></property><property name="custLevel" column="cust_level"></property><property name="custAddress" column="cust_address"></property><property name="custPhone" column="cust_phone"></property></class>
</hibernate-mapping>

2、编写Hibernate主配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration><session-factory><!-- 1、连接数据库的基本信息 --><property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property><property name="hibernate.connection.url">jdbc:mysql://localhost:3306/proxy</property><property name="hibernate.connection.username">root</property><property name="hibernate.connection.password">admin123</property><!-- 2、hibernate的基本配置 --><!-- 数据库的方言 --><property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property><!-- 是否显示SQL语句 --><property name="hibernate.show_sql">true</property><!-- 是否格式化SQL语句 --><property name="hibernate.format_sql">true</property><!-- 是否让hibernate根据表结构的变化来生成DDL语句--><property name="hibernate.hbm2ddl.auto">update</property><!-- 配置数据源的提供商 --><property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property><!-- 把session绑定到当前线程上 --><property name="hibernate.current_session_context_class">thread</property><!-- 3、映射文件的位置 --><mapping resource="cn/itcast/domain/Customer.hbm.xml"/></session-factory>
</hibernate-configuration>

3、编写HibernateUtil

package cn.itcast.utils;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;/*** hibernate的工具类* 用于获取Session对象* * 使用工具类原因:*    1.简化代码*     2.保证SessionFactory不会反复的创建和销毁**/
public class HibernateUtil {private static SessionFactory factory;static{try {Configuration cfg = new Configuration();cfg.configure();factory = cfg.buildSessionFactory();} catch (Exception e) {e.printStackTrace();throw new ExceptionInInitializerError("初始化SessionFactory失败!");}}/*** 每次都是从当前线程上获取Session* @return*/public static Session getCurrentSession(){return factory.getCurrentSession();}/*** 开启事务*/public static void beginTransaction(){getCurrentSession().beginTransaction();}/*** 提交事务*/public static void commit(){getCurrentSession().beginTransaction().commit();}/*** 回滚事务*/public static void rollback(){getCurrentSession().beginTransaction().rollback();}}

4、编写Dao层代码

package cn.itcast.dao;import java.util.List;import cn.itcast.domain.Customer;/*** 客户的持久层接口**/
public interface ICustomerDao {/*** 保存客户* @param customer*/void saveCustomer(Customer customer);/*** 查询所有客户* @return*/List<Customer> findAllCustomer();/*** 删除客户* @param customer*/void removeCustomer(Customer customer);/*** 根据id查询客户* @param custId* @return*/Customer findCustomerById(Long custId);/*** 更新客户* @param customer*/void updateCustomer(Customer customer);}
package cn.itcast.dao.impl;import java.util.List;import cn.itcast.dao.ICustomerDao;
import cn.itcast.domain.Customer;
import cn.itcast.utils.HibernateUtil;/*** 客户的持久层实现类**/
public class CustomerDaoImpl implements ICustomerDao {@Overridepublic void saveCustomer(Customer customer) {HibernateUtil.getCurrentSession().save(customer);}@Overridepublic List<Customer> findAllCustomer() {return HibernateUtil.getCurrentSession().createQuery("from Customer").list();}@Overridepublic void removeCustomer(Customer customer) {HibernateUtil.getCurrentSession().delete(customer);}@Overridepublic Customer findCustomerById(Long custId) {return HibernateUtil.getCurrentSession().get(Customer.class,custId);}@Overridepublic void updateCustomer(Customer customer) {HibernateUtil.getCurrentSession().update(customer);}}

5、编写Service层代码

package cn.itcast.service;import java.util.List;import cn.itcast.domain.Customer;/*** 客户的业务层接口**/
public interface ICustomerService {/*** 保存客户* @param customer*/void saveCustomer(Customer customer);/*** 查询所有客户* @return*/List<Customer> findAllCustomer();/*** 删除客户* @param customer*/void removeCustomer(Customer customer);/*** 根据id查询客户* @param custId* @return*/Customer findCustomerById(Long custId);/*** 修改客户* @param customer*/void updateCustomer(Customer customer);//void test();
}

(1)、没有用到动态代理之前的servcie层实现类

package cn.itcast.service.impl;import java.util.List;import org.hibernate.Session;
import org.hibernate.Transaction;import cn.itcast.dao.ICustomerDao;
import cn.itcast.dao.impl.CustomerDaoImpl;
import cn.itcast.domain.Customer;
import cn.itcast.service.ICustomerService;
import cn.itcast.utils.HibernateUtil;
/*** 客户的业务层实现类* 事务必须在此控制* 业务层都是调用持久层的方法*/
public class CustomerServiceImpl_OLD implements ICustomerService {private ICustomerDao customerDao = new CustomerDaoImpl();@Overridepublic void saveCustomer(Customer customer) {Session s = null;Transaction tx = null;try{s = HibernateUtil.getCurrentSession();tx = s.beginTransaction();customerDao.saveCustomer(customer);tx.commit();}catch(Exception e){tx.rollback();throw new RuntimeException(e);}}@Overridepublic Customer findCustomerById(Long custId) {Session s = null;Transaction tx = null;try{s = HibernateUtil.getCurrentSession();tx = s.beginTransaction();Customer c = customerDao.findCustomerById(custId);tx.commit();return c;}catch(Exception e){tx.rollback();throw new RuntimeException(e);}}@Overridepublic List<Customer> findAllCustomer() {  Session s = null;Transaction tx = null;try{s = HibernateUtil.getCurrentSession();tx = s.beginTransaction();List<Customer> cs = customerDao.findAllCustomer();tx.commit();return cs;}catch(Exception e){tx.rollback();throw new RuntimeException(e);}}@Overridepublic void removeCustomer(Customer customer) {   Session s = null;Transaction tx = null;try{s = HibernateUtil.getCurrentSession();tx = s.beginTransaction();customerDao.removeCustomer(customer);tx.commit();}catch(Exception e){tx.rollback();throw new RuntimeException(e);}}@Overridepublic void updateCustomer(Customer customer) {Session s = null;Transaction tx = null;try{s = HibernateUtil.getCurrentSession();tx = s.beginTransaction();customerDao.updateCustomer(customer);tx.commit();}catch(Exception e){tx.rollback();throw new RuntimeException(e);}}
}

(2)、用动态代理之后的service层实现类

package cn.itcast.service.impl;import java.util.List;import org.hibernate.Session;
import org.hibernate.Transaction;import cn.itcast.dao.ICustomerDao;
import cn.itcast.dao.impl.CustomerDaoImpl;
import cn.itcast.domain.Customer;
import cn.itcast.service.ICustomerService;
import cn.itcast.utils.HibernateUtil;
/*** 客户的业务层实现类* 事务必须在此控制* 业务层都是调用持久层的方法*/
public class CustomerServiceImpl implements ICustomerService {private ICustomerDao customerDao = new CustomerDaoImpl();@Overridepublic void saveCustomer(Customer customer) {customerDao.saveCustomer(customer);}@Overridepublic Customer findCustomerById(Long custId) {return customerDao.findCustomerById(custId);}@Overridepublic List<Customer> findAllCustomer() {  return customerDao.findAllCustomer();}@Overridepublic void removeCustomer(Customer customer) { customerDao.removeCustomer(customer);}@Overridepublic void updateCustomer(Customer customer) {customerDao.updateCustomer(customer);}
}

6、编写代理类

package cn.itcast.factory;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;import cn.itcast.service.ICustomerService;
import cn.itcast.service.impl.CustomerServiceImpl;
import cn.itcast.utils.HibernateUtil;public class BeanFactory {public static ICustomerService getCustomerService(){//1.定义一个业务层实现类对象final ICustomerService customerService = new CustomerServiceImpl();//2.生成业务层实现类对象的代理对象ICustomerService proxyCustomerService = (ICustomerService) Proxy.newProxyInstance(customerService.getClass().getClassLoader(), customerService.getClass().getInterfaces(), new InvocationHandler() {/*** 如何代理:*   就想再执行被代理对象的任何方法时,给它加上事务的支持*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object rtValue = null;try{//1.开启事务HibernateUtil.beginTransaction();//2.执行方法rtValue = method.invoke(customerService, args);//业务核心方法(业务层方法在执行)//3.提交事务HibernateUtil.commit();}catch(Exception e){//4.回滚事务HibernateUtil.rollback();}finally{//5.释放资源(hibernate帮我们释放了)
//                          HibernateUtil.getCurrentSession().close();}return rtValue;}});return proxyCustomerService;}
}

7、编写执行操作数据库的动作类

package cn.itcast.ui;import cn.itcast.domain.Customer;
import cn.itcast.factory.BeanFactory;
import cn.itcast.service.ICustomerService;
import cn.itcast.service.impl.CustomerServiceImpl;public class Client {public static void main(String[] args) {ICustomerService customerService = BeanFactory.getCustomerService();Customer c = new Customer();c.setCustName("proxy_aaa");customerService.saveCustomer(c);}}

spring学习笔记 -- day06 动态代理相关推荐

  1. Spring学习10之动态代理

    前言 优点 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务 公共业务交给了代理,实现了业务的分工 公共业务发生拓展时,方便集中管理 缺点: 一个真实的角色就会产生一个代理,代码量翻倍,开发效率 ...

  2. Spring学习笔记(三) AOP_annotation,AOP_XML

    在学习课程以前,听说AOP有种很神秘的感觉,好像很好深的技术.其实原理很简单,使用动态代理的方式给程序增加逻辑.与此相似的有struts2中的filter拦截器. 再讲AOP之前先把需求说一下: 同S ...

  3. Spring学习笔记之MyBatis

    系列文章目录 Spring学习笔记 之 Springhttps://blog.csdn.net/weixin_43985478/article/details/124411746?spm=1001.2 ...

  4. 【Spring学习笔记 九】Spring声明式事务管理实现机制

    什么是事务?事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部不起作用,关乎数据准确性的地方我们一定要用到事务,防止业务逻辑出错. 什么是事务管理,事务管理对于企业应用而言至 ...

  5. Spring 学习笔记----->AOP

    Spring 学习笔记----->AOP 代理模式 为什么学代理模式? 因为这就是Spring Aop的底层 代理模式的分类: 静态代理 动态代理 静态代理 生活用的例子: 房东 public ...

  6. JavaEE——Spring学习笔记03【AOP开发】

    JavaEE--Spring学习笔记01[Ioc开发的模式] JavaEE--Spring学习笔记02[Spring和Mybatis的整合] JavaEE--Spring学习笔记03[AOP开发] J ...

  7. JavaEE——Spring学习笔记01【Ioc开发的模式】

    JavaEE--Spring学习笔记01[Ioc开发的模式] JavaEE--Spring学习笔记02[Spring和Mybatis的整合] JavaEE--Spring学习笔记03[AOP开发] J ...

  8. CHY的Spring学习笔记---师从动力节点王鹤老师(B站白嫖)

    Spring学习笔记 核心技术:ioc和aop ioc:使用di(依赖注入)实现控制反转,底层使用的是反射机制 spring可以创建自己写的类的对象,也可以创建非自定义对象,只要知道类的全限定名即可. ...

  9. Spring 学习笔记(二)Spring AOP

    前言 容器和AOP是Spring的两大核心.本文将来学习Spring AOP. AOP是什么? AOP在计算机科学领域还是相对年轻的概念,由Xerox PARC公司发明.Gregor Kiczales ...

最新文章

  1. 苹果如何使用神经网络在点云中做对象检测
  2. 数据列表DataList模板之实例
  3. ALICE源代码分析
  4. Redis---概述
  5. 聚类分析在用户行为中的实例_看完这篇,你还敢说不懂聚类分析?
  6. QAdmin轻量级后台HTML模板 1.5
  7. 中英文对照 —— 心理/神经科学
  8. 忙了好一阵子了 才记起来我的博客园
  9. 【颜色识别】基于matlab GUI机器视觉RGB识别系统【含Matlab源码 951期】
  10. 台达JAVA_wplsoft下载(台达plc编程软件)
  11. 5. DICOM图像层级分类-DCMTK-压缩图像PixelData读取
  12. 电吉他弦距测试软件,测吉他弦距的简单方法
  13. pixi 平铺精灵 demo (一)
  14. 小程序发布上线-微信小程序开发-视频教程17
  15. CSS布局示例 1 - 页面色块布局
  16. 设计模式-行为型-访问者模式
  17. win10上安装ubunt18双系统过程中出现mmx64.efi not found问题
  18. 【深度学习框架输入格式】NCHW还是NHWC?
  19. 华为无线-Portal认证异常-无线强制切换为手机流量
  20. ROS中两轮差速底盘给定线速度和角速度值的合法性检查

热门文章

  1. ios 微博登录 21338错误 sso package or sign error
  2. C#利用委托事件解决银行还款问题
  3. Flink 实时去重方案
  4. 稻盛和夫告别演讲全文:人生因思维方式而改变
  5. 黑群晖宝塔配置zblog,wordpress.frp内网穿透记录(转载的)
  6. 云创大数据与宽泛科技签订战略合作协议
  7. 狂潮微课小红书推广引流教程
  8. 基站天线效率相关技术研究
  9. 高云FPGA(四):抓信号
  10. 创享投资贾珂:我们的“泛娱乐+”时代