深圳服装网站建设制作开发贵阳小程序开发软件公司
深圳服装网站建设制作开发,贵阳小程序开发软件公司,网站建设具体步骤,营销推广活动策划方案静态代理设计模式 代理设计模式最本质的特质#xff1a;一个真实业务主题只完成核心操作#xff0c;而所有与之辅助的功能都由代理类来完成。 例如#xff0c;在进行数据库更新的过程之中#xff0c;事务处理必须起作用#xff0c;所以此时就可以编写代理设计模式来完成。…静态代理设计模式 代理设计模式最本质的特质一个真实业务主题只完成核心操作而所有与之辅助的功能都由代理类来完成。 例如在进行数据库更新的过程之中事务处理必须起作用所以此时就可以编写代理设计模式来完成。 范例结合传统的代理设计模式以及以购物车CartDao为例来编写代理设计模式 package so.strong.mall.proxy;
import java.util.List;
public interface CartDao {boolean insert(Cart cart) throws Exception;ListCart findAll() throws Exception;
} 以上CartDao接口定义的方法更行插入一定需要事务控制对于查询操作不需要事务控制。 定义CartDao真实实现 package so.strong.mall.proxy;
import java.util.List;
public class CartDAOImpl implements CartDao{Overridepublic boolean insert(Cart cart) throws Exception {System.out.println(执行数据增加操作);return false;}Overridepublic ListCart findAll() throws Exception {System.out.println(执行数据列表操作);return null;}
} 定义代理主题类 package so.strong.mall.proxy;
import java.util.List;
public class CartDAOProxy implements CartDao {private CartDao cartDao;public CartDAOProxy() {}public void setCartDao(CartDao cartDao) {this.cartDao cartDao;}public void prepare() {System.out.println(取消掉jdbc的自动提交);}public void commit() {System.out.println(手工提交事务);}public void rollback() {System.out.println(出现错误事务回滚);}Overridepublic boolean insert(Cart cart) throws Exception {try {this.prepare();boolean flag this.cartDao.insert(cart);this.commit();return flag;} catch (Exception e) {this.rollback();throw e;}}Overridepublic ListCart findAll() throws Exception {return this.cartDao.findAll();}
} 业务层现在并不关心到底是代理类还是真实主题类它只关心一点只要取得了CartDao接口对象就可以那么这一操作可以通过工厂类来隐藏。 package so.strong.mall.proxy;
public class DAOFactory {public static CartDao getCartDaoInstance() {CartDAOProxy proxy new CartDAOProxy();proxy.setCartDao(new CartDAOImpl());return proxy;}
} 此时业务层暂时不需要继续进行只需要通过客户端模拟业务层调用即可。 public class TestDemo {
public static void main(String[] args) throws Exception{CartDao dao DAOFactory.getCartDaoInstance();dao.insert(new Cart());}
}
//取消掉jdbc的自动提交
//执行数据增加操作
//手工提交事务 因为事务和处理本身与核心业务有关的功能但是它不是核心那么用代理解决是最合适的方式。 动态代理设计模式 上面给出的代理设计模式的确可以完成代理要求但是有一个问题如果说现在项目里面有200张数据表那么至少也需要200个左右的DAO接口如果用上面的代理设计模式那么意味着除了编写200个的DAO接口实现还要编写200个代理类并且有意思的是这些代理类实现几乎相同。 以上的代理设计模式属于静态代理设计模式只能够作为代理模式的雏形出现并不能购作为代码使用的设计模式为此专门引入了动态代理设计模式的概念。 即利用一个代理类可以实现所有被代理的操作。 如果要想实现动态设计模式那么必须首先观察一个接口java.lang.reflect.InvocatonHandler. 它里面有一个方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; 这个方法就属于代理中调用真实主题类的操作方法这个方法里面的参数意义如下 Object proxy表示代理类的对象Method method表示现在正在调用的方法Object[] args表示方法里面的参数。但是这个方法没有所对应的真实对象所以需要在创建这个类对象的时候设置好真实代理对象。 如果要想找到代理对象则要使用java.lang.reflect.Proxy类来动态创建此类主要使用以下方法 public static Object newProxyInstance(ClassLoader loader,Class?[] interfaces,InvocationHandler h) throws IllegalArgumentException 此方法参数定义如下 ClassLoader loader 指的是取得对象的加载器Class?[] interfaces 代理设计模式的核心是围绕接口进行的所以此处必须取出全部的接口InvocationHandler h代理的实现类。 范例使用动态代理实现上面的代理 CartDao不变修改CartDAOProxy代理类 package so.strong.mall.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class CartDAOProxy implements InvocationHandler {private Object obj; //这个是真实对象主题/*** 将要操作的真实主题对象绑定到代理之中而后返回一个代理类对象* param obj 真实对象主题* return 代理类对象*/public Object bind(Object obj) {this.obj obj;return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(), this);}public void prepare() {System.out.println(取消掉jdbc的自动提交);}public void commit() {System.out.println(手工提交事务);}public void rollback() {System.out.println(出现错误事务回滚);}//只要执行了操作方法那么就一定会触发invokeOverridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object object null;//接收返回值if (method.getName().contains(insert)) { //更新插入类操作this.prepare();try {object method.invoke(this.obj, args); //反射调用方法this.commit();} catch (Exception e) {this.rollback();}} else {object method.invoke(this.obj, args);//查询操作不需要事务支持}return object;}
} //修改工厂
package so.strong.mall.proxy;
public class DAOFactory {public static Object getCartDaoInstance(Object realObject) {return new CartDAOProxy().bind(realObject);}
} //修改调用
package so.strong.mall.proxy;
public class TestDemo {public static void main(String[] args) throws Exception{CartDao dao (CartDao) DAOFactory.getCartDaoInstance(new CartDAOImpl());dao.insert(new Cart());}
} CGLIB实现动态代理设计模式 动态代理模式的确好用而且也解决了代理类重复的问题但是不管是传统静态代理或动态代理都有个设计缺陷以动态代理为例 return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); //传入真实主题类返回代理主题类 代理设计模式有一个硬性要求就是类必须要有接口所以业界很多人认为应该在没有接口的环境下也能使用代理设计模式。 所以在此时在开源社区里面提供了一个组件包——CGLIB利用此包可以在没有接口的情况下也能够使用动态代理设计模式它是模拟的类。 如果要想使用CGLIB那么必须首先搞清楚对应关系 Proxynet.sf.cglib.proxy.EnhancerInvocationHandlernet.sf.cglib.proxy.MethodInterceptor真实主题调用net.sf.cglib.proxy.MethodProxy老师课上使用的是引入CGLIB的jar包我去mvn仓库找了一下找到了一个cglib放到pom里面发现也可以。 dependencygroupIdcglib/groupIdartifactIdcglib/artifactIdversion2.2.2/version
/dependency 范例使用CGLIB实现动态代理设计模式 package so.strong.mall.proxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;class ItemDAOImpl {public void insert(Item item) {System.out.println(增加操作);}
}class MyProxy implements MethodInterceptor {private Object target; //真实操作主题public MyProxy(Object target) {this.target target;}Overridepublic Object intercept(Object proxy, Method method, Object[] args,MethodProxy methodProxy) throws Throwable {Object object null;this.prepare();object method.invoke(this.target, args);this.commit();return object;}public void prepare() {System.out.println(取消掉jdbc的自动提交);}public void commit() {System.out.println(手工提交事务);}
}public class TestCGLIB {public static void main(String[] args) {ItemDAOImpl itemDAO new ItemDAOImpl(); //真实主题对象//代理设计模式之中必须要有公共的集合点例如接口而CGLIB没有接口Enhancer enhancer new Enhancer(); //创建一个代理工具类enhancer.setSuperclass(ItemDAOImpl.class); //设置一个虚拟的父类enhancer.setCallback(new MyProxy(itemDAO)); //设置代理的回调操作ItemDAOImpl proxyDao (ItemDAOImpl) enhancer.create();proxyDao.insert(new Item());}
} 可以发现此时没有了对接口的依赖也可以实现动态代理设计但是需要模拟代理的父类对象。转载于:https://www.cnblogs.com/itermis/p/8940582.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/91869.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!