spring学习笔记 -- day06 动态代理
来源:互联网 发布:python 日期时间差 编辑:程序博客网 时间:2024/06/05 18:10
一、基于接口的动态代理
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);}}
阅读全文
0 0
- spring学习笔记 -- day06 动态代理
- web学习笔记19-静态代理,动态代理,spring AOP
- C++学习笔记 day06
- mysql 学习笔记 day06
- Oracle学习笔记--day06
- 动态代理学习笔记
- 动态代理学习笔记
- 动态代理学习笔记
- 动态代理学习笔记
- spring学习笔记(12)--Introduction-AOP中的动态代理
- Spring学习笔记(13)----动态代理模式分析演示
- Spring学习笔记之aop动态代理(3)
- Spring学习之动态代理
- 学习Spring之动态代理
- 静态代理和动态代理学习笔记
- java动态代理学习笔记
- java动态代理学习笔记
- java动态代理学习笔记
- ueditor的ctrl+enter和enter切换提交并且禁止换行
- AB模式与打包APK
- hdu 6130 Kolakoski (水题)
- 获取控件的绝对位置
- Boxoft WAV to MP3 Converter 1.1 漏洞分析及利用[SEH]
- spring学习笔记 -- day06 动态代理
- 多相机的视频拼接器
- ImageLoader
- ArcGIS Engine 类库介绍
- 学习java第七天
- poi做导出时遇到InvocationTargetException 异常
- 为什么Linux安全,基于它的安卓却被吐槽不安全
- 决策树
- Kaldi-ctc的安装与TIMIT实例