在项目中,我们经常会写到一些公共的代码,来让开发人员调用,减少代码重复,下面,我就将一些常用到的公共类贴出来和大家分享!!
在我们的项目中,经常会出现dao、daoImpl、service、serviceImpl这样操作数据库的类出现,然而我们在使用它们的时候都会在相应的类中通过new关键字生成其对象,然后调用里面相应的操作方法,这样有一个弊端出现,对象不好管理,程序的拓展性能比较差,当我们要修改相应的实现类的时候还要在类中进行修改,不好维护,所以我们将这些类中定义在一个XML配置文件中,程序员只要写好相应的类进行配置,然后调用公共类我们的对象就帮你生成好了,代码实现如下:
1、编写相应的Dao类和实现类:
package com.common.beanmanage; public interface Dao { public void addUser(); public void addUserCount(); }
package com.common.beanmanage; public class DaoImpl implements Dao { @Override public void addUser() { System.out.println("增加用户"); } @Override public void addUserCount() { System.out.println("增加用户账单"); } }package com.common.beanmanage; public interface Service { public void add(); }package com.common.beanmanage; public class ServiceImpl implements Service{ private Dao dao; public ServiceImpl(){ this.dao=(DaoImpl)BeanFactory.getInstance().getDaoObject(Dao.class); } @Override public void add() { dao.addUser(); dao.addUserCount(); } }
2、在配置文件中进行配置:beans.xml(相当于Spring中的依赖注入)
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="com.common.beanmanage" class="com.common.beanmanage.DaoImpl"></bean>
<bean id="com.common.beanmanage.Dao" class="com.common.beanmanage.DaoImpl"></bean>
<bean id="com.common.beanmanage.Service" class="com.common.beanmanage.ServiceImpl"></bean>
</beans>
3、编写生成实例的工厂类:package com.common.beanmanage; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * 创建Bean对象的管理类,对Bean对象进行管理 * 运用到的设计模式:单例模式和工厂模式 * @author Administrator * */ public class BeanFactory { private Document doc=null; private Map daoMap=new HashMap();//将class和创建好的对象放在Map中 private Map serviceMap=new HashMap();//将class和创建好的对象放在Map中 private static BeanFactory instance=new BeanFactory();//创建单例 //构造函数,解析XML private BeanFactory(){ try { doc=new SAXReader().read(Thread.currentThread().getContextClassLoader().getResourceAsStream("beans.xml")); } catch (DocumentException e) { e.printStackTrace(); } } //生成dao的实例,不需要进行事物封装 public synchronized Object getDaoObject(Class c){ if(daoMap.containsKey(c.getName())){ return daoMap.get(c.getName()); } Element root = doc.getRootElement(); List<Element> list=root.elements("bean"); String className=null; Object obj=null; for(Element e:list){ if(e.attribute("id").getStringValue().equals(c.getName())){ className=e.attributeValue("class"); break; } } if(className!=null){ try { obj=Class.forName(className).newInstance(); daoMap.put(c.getName(), obj); } catch (InstantiationException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } catch (ClassNotFoundException e1) { e1.printStackTrace(); } } return obj; } //生成service的实例,需要进行事物的封装 public synchronized Object getServiceObject(Class c){ if(serviceMap.containsKey(c.getName())){ return serviceMap.get(c.getName()); } Element root = doc.getRootElement(); List<Element> list=root.elements("bean"); String className=null; Object obj=null; for(Element e:list){ if(e.attribute("id").getStringValue().equals(c.getName())){ className=e.attributeValue("class"); break; } } if(className!=null){ try { obj=Class.forName(className).newInstance(); //当业务逻辑有事务需要处理的时候,对对象进行一层封装 TransactionHandler handler=new TransactionHandler(); obj=handler.newProxyInstance(obj); serviceMap.put(c.getName(), obj); } catch (InstantiationException e1) { e1.printStackTrace(); } catch (IllegalAccessException e1) { e1.printStackTrace(); } catch (ClassNotFoundException e1) { e1.printStackTrace(); } } return obj; } public static BeanFactory getInstance(){ return instance; } }
4、如果有事务要进行处理,我们还可以使用动态代理模式对事务进行封装处理,交给程序去处理,用户不用自己在方法中添加事务开启、提交或者回滚操作,使用代理模式实现
相当于Spring中的AOP,面向切面编程,一般在service方法里面对其进行封装,如上面的生成service实例package com.common.beanmanage; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.Connection; import com.common.db.ConnectionManager; import com.common.db.DbUtil; /** * 采用代理模式封装对事务的处理 * * @author Administrator * */ public class TransactionHandler implements InvocationHandler { private Object targetObject; public Object newProxyInstance(Object targetObject) { this.targetObject = targetObject; return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Connection conn = null; Object ret = null; try { //从ThreadLocal中取得Connection conn = ConnectionManager.getConnection(); if (method.getName().startsWith("add") || method.getName().startsWith("del") || method.getName().startsWith("modify")) { //手动控制事务提交 DbUtil.beginTransaction(conn); System.out.println("开启事物"); } //调用目标对象的业务逻辑方法 ret = method.invoke(targetObject, args); if (!conn.getAutoCommit()) { //提交事务 DbUtil.commitTransaction(conn); System.out.println("提交事物"); } // }catch(ApplicationException e) { // if (!conn.getAutoCommit()) { // //回滚事务 // ConnectionManager.rollbackTransaction(conn); // } // throw e; }catch(Exception e) { e.printStackTrace(); if (e instanceof InvocationTargetException) { InvocationTargetException ete = (InvocationTargetException)e; throw ete.getTargetException(); } if (!conn.getAutoCommit()) { //回滚事务 System.out.println("出现异常,不能提交"); DbUtil.rollbackTransaction(conn); } //throw new ApplicationException("操作失败!"); }finally { DbUtil.close(conn); } return ret; } }
5、编写我们的测试类package com.common.beanmanage; public class Client { private static Service service; static{ service=(Service)BeanFactory.getInstance().getServiceObject(Service.class); } public static void main(String[] args) { //service=(Service)BeanFactory.getInstance().getServiceObject(Service.class); service.add(); } }
这样,我们在程序里面不用通过new关键字来实现对象的生成,而是通过配置文件,由程序解析配置文件帮我们实现了,并且在service的实现类中,我们不用考虑事务的操作了,
只要编写我们的业务逻辑的实现即可,通过动态代理模式帮我们把事务给处理好了,在这个里面,我们实际上模仿了Spring中的AOP和IOC的基本实现!大家可以思考一下,
灵活运用。